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

ecs_entmail_ncs.c

/*============================================================================
 *  Définitions des fonctions
 *   associées à la structure `ecs_entmail_t' décrivant une entité de maillage
 *   et réalisant les sorties pour l'interfacage avec le Noyau
 *============================================================================*/

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

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


/*----------------------------------------------------------------------------
 *  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_def.h"
#include "ecs_comm.h"
#include "ecs_fic.h"
#include "ecs_tab.h"


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


/*----------------------------------------------------------------------------
 *  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_int.h"
#include "ecs_champ_comm.h"
#include "ecs_famille_chaine.h"
#include "ecs_param_perio_glob.h"


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

#include "ecs_entmail.h"
#include "ecs_entmail_pcp.h"


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

#include "ecs_entmail_ncs.h"


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

#include "ecs_entmail_priv.h"


/*============================================================================
 *                       Définition de macros
 *============================================================================*/

/*  Numéro de la famille par défaut (sans couleur ni groupe) */

#define ECS_NCS_FAMILLE_VAL_PAR_DEFAUT  0


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

/*----------------------------------------------------------------------------
 *  Fonction qui renvoie la liste des champs "famille"
 *   pour toutes les entités de maillage
 *  et qui détermine :
 *  - le nombre   de familles à transférer au Noyau
 *  - les numéros de famille  des cellules
 *  - les numéros de famille  des faces de bord
 *  - le nombre maximal de  propriétés des familles
 *  - les propriétés des familles
 *----------------------------------------------------------------------------*/

static ecs_champ_t * * ecs_loc_entmail_ncs__cree_fam
(
 size_t                          nbr_cel,
 size_t                          nbr_fac,
 ecs_tab_int_t     *const        liste_fac_de_bord,
 ecs_entmail_t     *const *const vect_entmail,
 ecs_famille_t     *const *const vect_fam_tete,
 int               *const        nbr_fam,
 int               *const        nbr_max_propr,
 ecs_tab_int_t     *const        tab_fam_cel,
 ecs_tab_int_t     *const        tab_fam_fac_de_bord,
 ecs_tab_int_t     *const        tab_propr_fam,
 ecs_tab_char_t    *const        noms_groupes
);


/*----------------------------------------------------------------------------
 *  Fonction qui affiche le nombre de cellules, faces internes, et faces
 *  de bord fournies en argument.
 *----------------------------------------------------------------------------*/

static void ecs_loc_entmail_ncs__aff_nbr_ent
(
 const ecs_int_t         nbr_elt_cel,
 const ecs_int_t         nbr_elt_fac_interne,
 const ecs_int_t         nbr_elt_fac_de_bord
) ;


/*----------------------------------------------------------------------------
 *  Fonction qui (re)numérote les groupes et construit un tableau contenant
 *   les noms ordonnés de ces groupes. Le tableau de chaînes de caractères
 *   noms_groupes doit initialement être vide.
 *----------------------------------------------------------------------------*/

static void ecs_loc_entmail_ncs__renum_groupes
(
       ecs_famille_t   *const *const vect_fam_tete,
 const ecs_int_t                     nbr_fam_ent[],
       ecs_tab_char_t         *const tab_propr_nom_fam_ent[],
       ecs_tab_char_t         *const noms_groupes
) ;


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

/*----------------------------------------------------------------------------
 *  Fonction qui écrit le fichier d'interface pour le Noyau de Code_Saturne.
 *----------------------------------------------------------------------------*/

void ecs_entmail_ncs__ecr
(
 ecs_bool_t                      simulate,
 ecs_entmail_t     *const *const vect_entmail,
 ecs_famille_t     *const *const vect_fam_tete,
 ecs_param_perio_t        *const liste_param_perio
)
{

  size_t          n_cells, n_faces, n_vertices, face_vertices_size ;

  ecs_int_t       nbr_fam ;
  ecs_int_t       nbr_max_propr ;

  ecs_int_t       nbr_per, nbr_per_rot ;
  ecs_int_t       ind_per ;

  size_t          ind_grp ;
  ecs_int_t     * pos_nom_grp ;
  char          * val_nom_grp ;

  ecs_tab_int_t   connect_fac_cel ;
  ecs_tab_int_t   liste_fac_de_bord ;
  ecs_tab_int_t   liste_fac_perio ;

  ecs_tab_int_t   nbr_fac_per ;

  ecs_tab_int_t   tab_fam_cel ;
  ecs_tab_int_t   tab_fam_fac ;
  ecs_tab_int_t   tab_propr_fam ;

  ecs_tab_char_t  tab_noms_groupes ;

  ecs_champ_t  * * vect_champ_famille ;

  ecs_comm_t    * comm ;


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


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

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

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

  face_vertices_size
    = ecs_champ__ret_val_nbr
        (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) ;


  nbr_per = ecs_champ_chaine__nbr_perio
    (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT]) ;

  nbr_per_rot = 0 ;

  for (ind_per = 0 ; ind_per < nbr_per ; ind_per++) {
    if (liste_param_perio[ind_per].type_perio == ECS_PERIO_TYPE_ROTA)
      nbr_per_rot++;
  }


  /*--------------------------------------------------------------------------*/
  /* Détermination :                                                          */
  /* - du nombre   de familles à transférer au Noyau                          */
  /* - des numéros de famille  des faces de bord                              */
  /* - du nombre maximal de  propriétés des familles                          */
  /* - des propriétés des familles                                            */
  /*--------------------------------------------------------------------------*/

  ecs_entmail_pcp__compte_typ_fac(vect_entmail,
                                  NULL,
                                  NULL,
                                  &liste_fac_de_bord,
                                  NULL) ;

  vect_champ_famille
    = ecs_loc_entmail_ncs__cree_fam(n_cells,
                                    n_faces,
                                    &liste_fac_de_bord,
                                    vect_entmail,
                                    vect_fam_tete,
                                    &nbr_fam,
                                    &nbr_max_propr,
                                    &tab_fam_cel,
                                    &tab_fam_fac,
                                    &tab_propr_fam,
                                    &tab_noms_groupes) ;

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

  BFT_FREE(vect_champ_famille) ;

  /* En cas de simulation seule, libération des tableaux temporaires
     et sortie directe */

  if (simulate == ECS_TRUE) {

    if (tab_propr_fam.nbr != 0)
      BFT_FREE(tab_propr_fam.val);
    if (tab_fam_cel.nbr != 0)
      BFT_FREE(tab_fam_cel.val);
    if (tab_fam_fac.nbr != 0)
      BFT_FREE(tab_fam_fac.val);

    return;
  }

  /* Initialisation de la communication vers le Noyau */
  /*--------------------------------------------------*/

  bft_printf(_("\n\nWrite output for Kernel\n"
               "-----------------------\n")) ;

  comm = ecs_comm_initialize() ;


  /*------------------------------------------------------------------------
   * Écriture des dimensions :
   *------------------------------------------------------------------------
   * - nombre de cellules
   * - nombre de faces
   * - nombre de sommets
   * - dimensionnement table de connectivité "faces -> sommets"
   * - nombre de familles
   * - nombre de propriétés max. des familles
   * - propriétés  des familles
   *------------------------------------------------------------------------*/


  ecs_comm_write_section("start_block:dimensions",
                         0,
                         0, 0, 0, true,
                         NULL,
                         ECS_TYPE_void,
                         comm) ;

  /* Écriture du nombre de cellules, faces, et sommets */

  ecs_comm_write_section("n_cells",
                         1,
                         1, 0, 0, true,
                         &n_cells,
                         ECS_TYPE_size_t,
                         comm) ;

  ecs_comm_write_section("n_faces",
                         1,
                         2, 0, 0, true,
                         &n_faces,
                         ECS_TYPE_size_t,
                         comm) ;

  ecs_comm_write_section("n_vertices",
                         1,
                         3, 0, 0, true,
                         &n_vertices,
                         ECS_TYPE_size_t,
                         comm) ;

  ecs_comm_write_section("face_vertices_size",
                         1,
                         0, 0, 1, true,
                         &face_vertices_size,
                         ECS_TYPE_size_t,
                         comm) ;


  /* Écriture du nombre de familles (on ne compte pas la famille `0') */

  ecs_comm_write_section("n_group_classes",
                         1,
                         0, 0, 1, true,
                         &nbr_fam,
                         ECS_TYPE_ecs_int_t,
                         comm) ;


  /* Écriture du nombre de propriétés max. des familles */

  ecs_comm_write_section("n_group_class_props_max",
                         1,
                         0, 0, 1, true,
                         &nbr_max_propr,
                         ECS_TYPE_ecs_int_t,
                         comm) ;


  /* Écriture des noms de groupes si lieu */

  if (tab_noms_groupes.nbr > 0) {

    ecs_comm_write_section("n_groups",
                           1,
                           0, 0, 1, true,
                           &(tab_noms_groupes.nbr),
                           ECS_TYPE_size_t,
                           comm) ;

    BFT_MALLOC(pos_nom_grp, tab_noms_groupes.nbr + 1, ecs_int_t) ;

    pos_nom_grp[0] = 1 ;
    for (ind_grp = 0 ; ind_grp < tab_noms_groupes.nbr ; ind_grp++)
      pos_nom_grp[ind_grp + 1]
        = pos_nom_grp[ind_grp] + strlen(tab_noms_groupes.val[ind_grp]) + 1 ;

    ecs_comm_write_section("group_name_index",
                           tab_noms_groupes.nbr + 1,
                           0, 1, 1, true,
                           pos_nom_grp,
                           ECS_TYPE_ecs_int_t,
                           comm) ;

    BFT_MALLOC(val_nom_grp, pos_nom_grp[tab_noms_groupes.nbr] - 1, char) ;

    for (ind_grp = 0 ; ind_grp < tab_noms_groupes.nbr ; ind_grp++)
      strcpy(val_nom_grp + (pos_nom_grp[ind_grp] - 1),
             tab_noms_groupes.val[ind_grp]) ;

    ecs_comm_write_section("group_name",
                           pos_nom_grp[tab_noms_groupes.nbr] - 1,
                           0, 1, 1, true,
                           val_nom_grp,
                           ECS_TYPE_char,
                           comm) ;

    BFT_FREE(pos_nom_grp) ;
    BFT_FREE(val_nom_grp) ;

    for (ind_grp = 0 ; ind_grp < tab_noms_groupes.nbr ; ind_grp++)
      BFT_FREE(tab_noms_groupes.val[ind_grp]) ;
    BFT_FREE(tab_noms_groupes.val) ;
    tab_noms_groupes.nbr = 0 ;

  }


  /* Écriture des propriétés des familles   */
  /* - propriétés des familles des cellules */
  /* - propriétés des familles des faces    */
  /* Pas de propriété pour la famille `0'   */

  ecs_comm_write_section("group_class_properties",
                         nbr_fam * nbr_max_propr,
                         0, 0, nbr_max_propr, true,
                         tab_propr_fam.val,
                         ECS_TYPE_ecs_int_t,
                         comm) ;


  /* Écritures supplémentaires pour la périodicité */

  if (nbr_per > 0) {

    /* nombre total de périodicités */

    ecs_comm_write_section("n_periodic_directions",
                           1,
                           0, 0, 1, true,
                           &nbr_per,
                           ECS_TYPE_ecs_int_t,
                           comm) ;

    /* nombre de périodicités de rotation */

    ecs_comm_write_section("n_periodic_rotations",
                           1,
                           0, 0, 1, true,
                           &nbr_per_rot,
                           ECS_TYPE_ecs_int_t,
                           comm) ;

    /* Nombre de faces périodiques */

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

    ecs_comm_write_section("n_periodic_faces",
                           nbr_fac_per.nbr,
                           0, 0, 1, true,
                           nbr_fac_per.val,
                           ECS_TYPE_ecs_int_t,
                           comm) ;

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

  }

  if (tab_propr_fam.nbr != 0)
    BFT_FREE(tab_propr_fam.val);


  /* Passage du bloc des dimensions au bloc des données */
  /*----------------------------------------------------*/

  ecs_comm_write_section("end_block:dimensions",
                         0,
                         0, 0, 0, true,
                         NULL,
                         ECS_TYPE_void,
                         comm) ;

  ecs_comm_write_section("start_block:data",
                         0,
                         0, 0, 0, true,
                         NULL,
                         ECS_TYPE_void,
                         comm) ;


  /*---------------------------------------------------------------
   * Écriture des données :
   *---------------------------------------------------------------
   * - connectivité faces -> cellules voisines
   * - numeros     de  famille
   * - positions   des sommets des faces
   * - connectivité faces -> sommets
   * - coordonnées des sommets
   *---------------------------------------------------------------*/


  /* Écriture de la connectivité faces -> cellules voisines */

  connect_fac_cel
    = ecs_champ_def__fac_cel
        (vect_entmail[ECS_ENTMAIL_CEL]->champ[ECS_CHAMP_DEF],
         vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) ;

  ecs_comm_write_section("face_cells",
                         n_faces * 2,
                         2, 0, 2, false,
                         connect_fac_cel.val,
                         ECS_TYPE_ecs_int_t,
                         comm) ;

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


  /* Écriture des numéros de famille des cellules */

  ecs_comm_write_section("cell_group_class_id",
                         tab_fam_cel.nbr,
                         1, 0, 1, false,
                         tab_fam_cel.val,
                         ECS_TYPE_ecs_int_t,
                         comm) ;


  /* Écriture des numéros de famille des faces */

  ecs_comm_write_section("face_group_class_id",
                         tab_fam_fac.nbr,
                         2, 0, 1, false,
                         tab_fam_fac.val,
                         ECS_TYPE_ecs_int_t,
                         comm) ;


  /* Écriture des positions des sommets des faces */

  ecs_champ_comm__ecr_pos(vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF],
                          "face_vertices_index",
                          2, 1,
                          comm) ;


  /* Écriture de la connectivité "faces -> sommets" */

  ecs_champ_comm__ecr(vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF],
                      "face_vertices",
                      2, 1, 1,
                      comm) ;


  /* Écriture des coordonnées des sommets */

  ecs_champ_comm__ecr(vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_DEF],
                      "vertex_coords",
                      1, 0, 3,
                      comm) ;


  /* Écritures supplémentaires pour la périodicité */
  /*-----------------------------------------------*/

  if (nbr_per > 0) {

    ecs_int_t   type_perio ;
    char        nom_param[32 + 1] ;


    /* Liste des paramètres de périodicité pour chacune d'entre elles */

    for (ind_per = 0 ; ind_per < nbr_per ; ind_per++) {

      int i, j;
      ecs_real_t  mat_h[3][4];

      /* Calcul de la matrice de transformation en coordonées homogènes */

      for (i = 0; i < 3; i++) {
        for (j = 0; j < 4; j++)
          mat_h[i][j] = 0.0;
      }

      if (liste_param_perio[ind_per].type_perio == ECS_PERIO_TYPE_TRANS) {

        for (i = 0; i < 3; i++) {
          mat_h[i][i] = 1.;
          mat_h[i][3] = liste_param_perio[ind_per].translation[i];
        }

      }
      else if (liste_param_perio[ind_per].type_perio == ECS_PERIO_TYPE_ROTA) {

        for (i = 0; i < 3; i++) {
          for (j = 0; j < 3; j++)
            mat_h[i][j] = liste_param_perio[ind_per].matrice[i][j];
        }
        for (i = 0; i < 3; i++)
          mat_h[i][3] = - mat_h[i][0]*liste_param_perio[ind_per].point_inv[0]
                        - mat_h[i][1]*liste_param_perio[ind_per].point_inv[1]
                        - mat_h[i][2]*liste_param_perio[ind_per].point_inv[2]
                        + liste_param_perio[ind_per].point_inv[i];

        for (i = 0; i < 3; i++) { /* Clipper les valeurs "nulles" */
          for (j = 0; j < 4; j++)
            if (ECS_ABS(mat_h[i][j]) < 1.e-16)
              mat_h[i][j] = 0.;
        }
      }

      /* Écriture des données associées */

      type_perio = (ecs_int_t)(liste_param_perio[ind_per].type_perio) ;

      sprintf(nom_param, "%s%02d", "periodicity_type_",
              liste_param_perio[ind_per].num_perio) ;

      ecs_comm_write_section(nom_param,
                             1,
                             0, 0, 1, true,
                             &type_perio,
                             ECS_TYPE_ecs_int_t,
                             comm) ;

      sprintf(nom_param, "%s%02d", "periodicity_matrix_",
              liste_param_perio[ind_per].num_perio) ;

      ecs_comm_write_section(nom_param,
                             3*4,
                             0, 0, 4, true,
                             mat_h,
                             ECS_TYPE_ecs_real_t,
                             comm) ;

      /* Informations pour la création des joints périodiques */

      liste_fac_perio
        = ecs_champ_chaine__liste_fac_perio
            (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT],
             ind_per + 1) ;

      sprintf(nom_param, "%s%02d", "periodicity_faces_",
              ind_per + 1) ;

      ecs_comm_write_section(nom_param,
                             liste_fac_perio.nbr,
                             0, 0, 2, false,
                             liste_fac_perio.val,
                             ECS_TYPE_ecs_int_t,
                             comm) ;

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

    }

  } /* Fin des écritures supplémentaires pour la périodicité */


  /* Ecriture de la rubrique de fin  du bloc sur les données */
  /*---------------------------------------------------------*/

  ecs_comm_write_section("end_block:data",
                         0,
                         0, 0, 0, true,
                         NULL,
                         ECS_TYPE_void,
                         comm) ;

  /* Ecriture de la rubrique de fin de fichier et fermeture */

  ecs_comm_write_section("EOF",
                         0,
                         0, 0, 0, true,
                         NULL,
                         ECS_TYPE_void,
                         comm) ;


  /* Fermeture du fichier de communication */
  /*---------------------------------------*/

  ecs_comm_finalize(&comm) ;


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

  if (tab_fam_cel.nbr != 0)
    BFT_FREE(tab_fam_cel.val);

  if (tab_fam_fac.nbr != 0)
    BFT_FREE(tab_fam_fac.val);

}


/*============================================================================
 *                              Fonctions privees
 *============================================================================*/


/*----------------------------------------------------------------------------
 *  Fonction qui renvoie la liste des champs "famille"
 *   pour toutes les entités de maillage
 *  et qui détermine :
 *  - le nombre   de familles à transférer au Noyau
 *  - le nombre maximal de  propriétés des familles
 *  - les numéros de famille  des cellules
 *  - les numéros de famille  des faces
 *  - les numéros à affecter aux groupes (et inversement, les noms par numéro)
 *  - les propriétés des familles
 *----------------------------------------------------------------------------*/

static ecs_champ_t * * ecs_loc_entmail_ncs__cree_fam
(
 size_t                          nbr_cel,
 size_t                          nbr_fac,
 ecs_tab_int_t     *const        liste_fac_de_bord,
 ecs_entmail_t     *const *const vect_entmail,
 ecs_famille_t     *const *const vect_fam_tete,
 int               *const        nbr_fam,
 int               *const        nbr_max_propr,
 ecs_tab_int_t     *const        tab_fam_cel,
 ecs_tab_int_t     *const        tab_fam_fac,
 ecs_tab_int_t     *const        tab_propr_fam,
 ecs_tab_char_t    *const        noms_groupes
)
{

  ecs_bool_t      bool_cree_fam_par_defaut ;

  size_t          cpt_fam ;
  size_t          cpt_prop ;
  size_t          decal_fam_ent ;
  size_t          icel ;
  size_t          ient ;
  size_t          ifac ;
  ecs_int_t       ifam ;
  size_t          igrp ;
  size_t          ipropr ;
  size_t          nbr_cel_avec_fam_defaut ;
  size_t          nbr_fac_avec_fam_defaut ;
  size_t          nbr_fbr_avec_fam_defaut ;
  ecs_int_t       nbr_fam_tot ;
  ecs_int_t       nbr_loc_propr ;
  ecs_int_t       num_fam_defaut ;

  ecs_int_t     * cpt_elt_ent_fam ;
  ecs_int_t       nbr_fam_ent[ECS_ENTMAIL_FIN] ;

  ecs_int_t       left ;
  ecs_int_t       right ;
  ecs_int_t       mid ;
  ecs_int_t       num_grp_loc ;
  char          * nom_grp_loc ;

  ecs_champ_t   * * vect_champ_famille ;

  ecs_famille_t   * fam_tete_ent ;
  ecs_famille_t   * fam_tete_globale ;

  ecs_tab_int_t     tab_nbr_cel_fam ;
  ecs_tab_int_t     tab_nbr_fac_fam ;
  ecs_tab_int_t     tab_nbr_fbr_fam ;
  ecs_tab_int_t   * tab_propr_ide_fam_ent[ECS_ENTMAIL_FIN] ;
  ecs_tab_char_t  * tab_propr_nom_fam_ent[ECS_ENTMAIL_FIN] ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  noms_groupes->nbr  = 0 ;
  noms_groupes->val = NULL ;


  BFT_MALLOC(vect_champ_famille, ECS_ENTMAIL_FIN, ecs_champ_t *) ;


  nbr_fam_tot = 0 ;

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

    assert(vect_entmail[ient] != NULL) ;

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

      vect_champ_famille[ient] =
        ecs_champ_chaine__trouve_nom(vect_entmail[ient]->champ[ECS_CHAMP_ATT],
                                     ECS_CHAMP_NOM_FAMILLE) ;

    }
    else {

      vect_champ_famille[ient] = NULL ;

    }


    if (vect_champ_famille[ient] != NULL) {

      nbr_fam_ent[ient] = ecs_famille_chaine__ret_nbr(vect_fam_tete[ient]) ;
      nbr_fam_tot += nbr_fam_ent[ient] ;

    }
    else {

      assert(vect_fam_tete[ient] == NULL) ;

      nbr_fam_ent[ient] = 0 ;

    }

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


  tab_nbr_cel_fam.nbr = nbr_fam_tot ;
  tab_nbr_fac_fam.nbr = nbr_fam_tot ;
  tab_nbr_fbr_fam.nbr = nbr_fam_tot ;

  if (nbr_fam_tot != 0) {
    BFT_MALLOC(tab_nbr_cel_fam.val,
               tab_nbr_cel_fam.nbr, ecs_int_t) ;
    BFT_MALLOC(tab_nbr_fac_fam.val,
               tab_nbr_fac_fam.nbr, ecs_int_t) ;
    BFT_MALLOC(tab_nbr_fbr_fam.val,
               tab_nbr_fbr_fam.nbr, ecs_int_t) ;
  }
  else {
    tab_nbr_cel_fam.val = NULL ;
    tab_nbr_fac_fam.val = NULL ;
    tab_nbr_fbr_fam.val = NULL ;
  }

  num_fam_defaut = nbr_fam_tot + 1 ;


  /* Numéros des familles des cellules */
  /*-----------------------------------*/

  if (vect_champ_famille[ECS_ENTMAIL_CEL] != NULL && nbr_cel != 0) {

    *tab_fam_cel
      = ecs_champ_att__fam_elt(vect_champ_famille[ECS_ENTMAIL_CEL],
                               &tab_nbr_cel_fam) ;

  }
  else {

    BFT_MALLOC(tab_fam_cel->val, nbr_cel, ecs_int_t) ;
    tab_fam_cel->nbr = nbr_cel ;

    for (icel = 0 ; icel < nbr_cel ; icel++)
      tab_fam_cel->val[icel] = num_fam_defaut ;

    for (ifam = 0 ; ifam < nbr_fam_tot ; ifam++)
      tab_nbr_cel_fam.val[ifam] = 0 ;

  }

  nbr_cel_avec_fam_defaut = 0 ;

  for (icel = 0 ; icel < nbr_cel ; icel++) {
    if (tab_fam_cel->val[icel] == 0) {
      tab_fam_cel->val[icel] = num_fam_defaut ;
      nbr_cel_avec_fam_defaut++ ;
    }
  }


  /* Numéros des familles des faces */
  /*--------------------------------*/

  if (vect_champ_famille[ECS_ENTMAIL_FAC] != NULL) {

    *tab_fam_fac
      = ecs_champ_att__fam_elt(vect_champ_famille[ECS_ENTMAIL_FAC],
                               &tab_nbr_fac_fam) ;

  }
  else {

    BFT_MALLOC(tab_fam_fac->val, nbr_fac, ecs_int_t) ;
    tab_fam_fac->nbr = nbr_fac ;

    for (ifac = 0 ; ifac < nbr_fac ; ifac++)
      tab_fam_fac->val[ifac] = num_fam_defaut ;

    for (ifam = 0 ; ifam < nbr_fam_tot ; ifam++)
      tab_nbr_fac_fam.val[ifam] = 0 ;

  }

  nbr_fac_avec_fam_defaut = 0 ;
  nbr_fbr_avec_fam_defaut = 0 ;

  for (ifac = 0 ; ifac < nbr_fac ; ifac++) {
    if (tab_fam_fac->val[ifac] == 0) {
      tab_fam_fac->val[ifac] = num_fam_defaut ;
      nbr_fac_avec_fam_defaut++ ;
    }
  }

  for (ifam = 0 ; ifam < (ecs_int_t)(tab_nbr_fbr_fam.nbr) ; ifam++)
    tab_nbr_fbr_fam.val[ifam] = 0 ;

  if (nbr_fam_tot > 0) {
    for (ifac = 0 ; ifac < liste_fac_de_bord->nbr ; ifac++) {
      if (tab_fam_fac->val[liste_fac_de_bord->val[ifac]] == num_fam_defaut)
        nbr_fbr_avec_fam_defaut++ ;
      else
        tab_nbr_fbr_fam.val
          [tab_fam_fac->val[liste_fac_de_bord->val[ifac]] - 1] += 1 ;
    }
  }
  else
    nbr_fbr_avec_fam_defaut += liste_fac_de_bord->nbr ;


  /*-------------------------------------------------------*/
  /* Détermination du  nombre  de  propriétés des familles */
  /* Détermination             des propriétés des familles */
  /*-------------------------------------------------------*/


  *nbr_max_propr = 1 ;

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

    if (vect_fam_tete[ient] != NULL) {

      tab_propr_ide_fam_ent[ient]
        = ecs_famille_chaine__ret_ide(vect_fam_tete[ient]) ;

      tab_propr_nom_fam_ent[ient]
        = ecs_famille_chaine__ret_nom(vect_fam_tete[ient]) ;

      /* Calcul du nombre maximal de propriétés */
      for (ifam = 0 ; ifam < nbr_fam_ent[ient] ; ifam++) {
        nbr_loc_propr =   tab_propr_ide_fam_ent[ient][ifam].nbr
                        + tab_propr_nom_fam_ent[ient][ifam].nbr ;
        *nbr_max_propr = ECS_MAX(*nbr_max_propr, nbr_loc_propr) ;
      }

    }

  }

  /* Mise à jour du tableau des numéros locaux des groupes */

  ecs_loc_entmail_ncs__renum_groupes(vect_fam_tete,
                                     nbr_fam_ent,
                                     tab_propr_nom_fam_ent,
                                     noms_groupes) ;

  if (nbr_fam_tot != 0) {

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

      cpt_elt_ent_fam = NULL ;

      if (vect_champ_famille[ient] != NULL) {

        /* Nombre d'éléments par entité et par famille */
        cpt_elt_ent_fam
          = ecs_champ_att__ret_nbr_elt_val(vect_champ_famille[ient],
                                           nbr_fam_tot) ;

      }
      else {

        BFT_MALLOC(cpt_elt_ent_fam, nbr_fam_tot, ecs_int_t) ;
        for (ifam = 0 ; ifam < nbr_fam_tot ; ifam++)
          cpt_elt_ent_fam[ifam] = 0 ;

      }

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

    }

  }


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

  bft_printf(_("\n\n"
               "Definition of face and cell families\n"
               "------------------------------------\n\n")) ;

  if (nbr_fac_avec_fam_defaut > 0) {

    /* On a du attribuer une famille par défaut à certaines faces */

    if (nbr_fbr_avec_fam_defaut > 0)
      ecs_warn() ;

    bft_printf
      (_("%d faces from a total of %d have no color\n"
         "and belong to no group...\n"
         "A default family is assigned to those faces.\n\n"),
       (int)nbr_fac_avec_fam_defaut, (int)nbr_fac) ;

  }

  if (nbr_cel_avec_fam_defaut > 0) {

    /* On a du attribuer une famille par défaut à certaines cellules */

    ecs_warn() ;
    bft_printf
      (_("%d cells from a total of %d have no color\n"
         "and belong to no group...\n"
         "A default family is assigned to those cells.\n\n"),
       (int)nbr_cel_avec_fam_defaut, (int)nbr_cel) ;

  }


  cpt_fam = 0 ;

  if (   nbr_fac_avec_fam_defaut > 0
      || nbr_cel_avec_fam_defaut         > 0)
    bool_cree_fam_par_defaut = ECS_TRUE ;
  else
    bool_cree_fam_par_defaut = ECS_FALSE ;


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

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

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

      ecs_loc_entmail_ncs__aff_nbr_ent
        (tab_nbr_cel_fam.val[cpt_fam],
         (tab_nbr_fac_fam.val[cpt_fam] - tab_nbr_fbr_fam.val[cpt_fam]),
         tab_nbr_fbr_fam.val[cpt_fam]) ;

      cpt_fam++ ;

    }

  }

  if (nbr_fam_tot != 0) {

    if (tab_nbr_cel_fam.nbr != 0)
      BFT_FREE(tab_nbr_cel_fam.val) ;

    if (tab_nbr_fac_fam.nbr != 0)
      BFT_FREE(tab_nbr_fac_fam.val) ;

    if (tab_nbr_fbr_fam.nbr != 0)
      BFT_FREE(tab_nbr_fbr_fam.val) ;

  }

  /* Affichage famille par défaut si nécessaire */

  if (bool_cree_fam_par_defaut == ECS_TRUE) {

    bft_printf("  %s %" ECS_FORMAT_ecs_int_t "\n", _("Family"),
               cpt_fam + 1) ;

    bft_printf("  %*s%s\n", strlen(_("Family")) + 1, "",
               _("Default family")) ;
    bft_printf("  %*s%s\n", strlen(_("Family")) + 1, "",
               _("(with no color nor group)")) ;

    /* Comme on ne traite pas les faces internes, inutile d'affecter la */
    /* famille par défaut à celles n'appartenant pas à une famille > 0  */

    ecs_loc_entmail_ncs__aff_nbr_ent
      (nbr_cel_avec_fam_defaut,
       (nbr_fac_avec_fam_defaut - nbr_fbr_avec_fam_defaut),
       nbr_fbr_avec_fam_defaut) ;


  } /* Fin : si affichage de la famille par défaut */


  /* Affichage des couleurs et des groupes en fonction des familles */
  /*----------------------------------------------------------------*/

  if (nbr_fam_tot != 0) {

    /* Affichage du titre */

    bft_printf(_("\n\nDefinition of colors and groups"
                 " based on families\n"
                 "-------------------------------"
                 "------------------\n\n")) ;


    fam_tete_globale = NULL ;

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

      fam_tete_ent = ecs_famille_chaine__copie(vect_fam_tete[ient]) ;

      ecs_famille_chaine__ajoute(&fam_tete_globale,
                                 fam_tete_ent) ;

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


    ecs_famille_chaine__aff_fam_att(fam_tete_globale) ;


    ecs_famille_chaine__detruit(&fam_tete_globale) ;

    /* Affichage des numéros et noms de groupes si lieu */

    if (noms_groupes->nbr > 0) {

      bft_printf(_("\n\n"
                   "Groups numbering\n"
                   "----------------\n\n")) ;

      for (igrp   = 0 ; igrp < noms_groupes->nbr ; igrp++)
        bft_printf(_("  Group %3d : \"%s\"\n"),
                   igrp + 1, noms_groupes->val[igrp]);

    }

  } /* Fin : s'il y a au moins une famille */


  *nbr_fam = cpt_fam ;
  if (bool_cree_fam_par_defaut == ECS_TRUE)
    *nbr_fam += 1 ;


  /* Concaténation des propriétés des familles */
  /*-------------------------------------------*/

  /* Pas de propriétés pour la famille 0 */

  tab_propr_fam->nbr = (*nbr_fam) * (*nbr_max_propr) ;
  BFT_MALLOC(tab_propr_fam->val, tab_propr_fam->nbr, ecs_int_t);

  /* Liste des propriétés des familles  */

  /* Attention : pour le noyau on n'écrit pas les propriétés par famille */
  /*             mais on écrit les i-emes propriétés de toutes           */

  decal_fam_ent = 0 ;

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

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

      cpt_prop = 0 ;

      /* Couleurs */

      for (ipropr = 0 ;
           ipropr < tab_propr_ide_fam_ent[ient][ifam].nbr ; ipropr++) {

        if (tab_propr_ide_fam_ent[ient][ifam].val[ipropr] >= 0) {
          tab_propr_fam->val[decal_fam_ent + cpt_prop * (*nbr_fam) + ifam]
            = tab_propr_ide_fam_ent[ient][ifam].val[ipropr] ;
          cpt_prop++ ;
        }

      }

      /* Groupes */

      for (ipropr = 0 ;
           ipropr < tab_propr_nom_fam_ent[ient][ifam].nbr ; ipropr++) {

        /* Recherche par dichotomie dans le tableau des groupes */

        nom_grp_loc = tab_propr_nom_fam_ent[ient][ifam].val[ipropr] ;

        left  = 0 ;
        right = noms_groupes->nbr - 1 ;

        while ((right - left) > 1) {

          mid = (right + left) / 2 ;  /* Division entière */
          if (strcmp(nom_grp_loc, noms_groupes->val[mid]) <= 0)
            right = mid ;
          else
            left  = mid ;

        }

        if (strcmp(nom_grp_loc, noms_groupes->val[right]) == 0)
          num_grp_loc = -(right + 1) ;
        else if (strcmp(nom_grp_loc, noms_groupes->val[left]) == 0)
          num_grp_loc = -(left + 1) ;
        else {
          assert(0) ;
          num_grp_loc = 0 ;
        }

        tab_propr_fam->val[decal_fam_ent + cpt_prop * (*nbr_fam) + ifam]
          = num_grp_loc ;

        cpt_prop++ ;

      }

      /* On complète par des '0' */

      for (ipropr = cpt_prop ;
           ipropr < (size_t)(*nbr_max_propr) ; ipropr++)
        tab_propr_fam->val[decal_fam_ent + ipropr * (*nbr_fam) + ifam] = 0 ;

    }

    decal_fam_ent += nbr_fam_ent[ient] ;

  }

  if (bool_cree_fam_par_defaut == ECS_TRUE) {

    /* On remplit la famille par défaut avec des '0' */

    for (ipropr = 0 ; ipropr < (size_t)(*nbr_max_propr) ; ipropr++)
      tab_propr_fam->val[decal_fam_ent + ipropr * (*nbr_fam)] = 0 ;

  }

  for (ient =  (ecs_int_t)ECS_ENTMAIL_CEL ;
       ient >= (ecs_int_t)ECS_ENTMAIL_FAC ; ient--) {
    for (ifam = 0 ; ifam < nbr_fam_ent[ient] ; ifam++) {
      BFT_FREE(tab_propr_ide_fam_ent[ient][ifam].val) ;
      BFT_FREE(tab_propr_nom_fam_ent[ient][ifam].val) ;
    }
    if (nbr_fam_ent[ient] != 0) {
      BFT_FREE(tab_propr_ide_fam_ent[ient]) ;
      BFT_FREE(tab_propr_nom_fam_ent[ient]) ;
    }
  }


  return vect_champ_famille ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui affiche le nombre de cellules, faces internes, et faces
 *  de bord fournies en argument.
 *----------------------------------------------------------------------------*/

static void ecs_loc_entmail_ncs__aff_nbr_ent
(
 const ecs_int_t         nbr_elt_cel,
 const ecs_int_t         nbr_elt_fac_interne,
 const ecs_int_t         nbr_elt_fac_de_bord
)
{

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/

  size_t lng_var_nbr ;

  lng_var_nbr = strlen(_("Number of cells")) ;
  lng_var_nbr = ECS_MAX(lng_var_nbr, strlen(_("Number of internal faces"))) ;
  lng_var_nbr = ECS_MAX(lng_var_nbr, strlen(_("Number of boundary faces"))) ;

  if (nbr_elt_cel > 0) {
    bft_printf("  ") ;
    ecs_print_padded_str(_("Number of cells"), lng_var_nbr) ;
    bft_printf(" : %*ld\n", ECS_LNG_AFF_ENT, (long)nbr_elt_cel) ;
  }

  if (nbr_elt_fac_interne > 0) {
    bft_printf("  ") ;
    ecs_print_padded_str(_("Number of internal faces"), lng_var_nbr) ;
    bft_printf(" : %*ld\n", ECS_LNG_AFF_ENT, (long)nbr_elt_fac_interne) ;
  }

  if (nbr_elt_fac_de_bord > 0) {
    bft_printf("  ") ;
    ecs_print_padded_str(_("Number of boundary faces"), lng_var_nbr) ;
    bft_printf(" : %*ld\n", ECS_LNG_AFF_ENT, (long)nbr_elt_fac_de_bord) ;
  }

}


/*----------------------------------------------------------------------------
 *  Fonction qui (re)numérote les groupes et construit un tableau contenant
 *   les noms ordonnés de ces groupes. Le tableau de chaînes de caractères
 *   noms_groupes doit initialement être vide.
 *----------------------------------------------------------------------------*/

static void ecs_loc_entmail_ncs__renum_groupes
(
       ecs_famille_t   *const *const vect_fam_tete,
 const ecs_int_t                     nbr_fam_ent[],
       ecs_tab_char_t         *const tab_propr_nom_fam_ent[],
       ecs_tab_char_t         *const noms_groupes
)
{

  size_t          ient ;
  ecs_int_t       ifam ;
  size_t          iloc ;
  size_t          ind ;

  size_t          cpt_nom_tot ;

  ecs_tab_int_t   tab_renum ;

  ecs_tab_char_t  tab_nom_cat ;
  ecs_tab_char_t  tab_nom_trie ;
  ecs_tab_char_t  tab_nom_cpct ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  noms_groupes->nbr = 0 ;
  noms_groupes->val = NULL ;


  /* Comptage */

  cpt_nom_tot = 0 ;

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

    if (vect_fam_tete[ient] != NULL) {

      for (ifam = 0 ; ifam < nbr_fam_ent[ient] ; ifam++)
        cpt_nom_tot += tab_propr_nom_fam_ent[ient][ifam].nbr ;

    }

  }

  tab_nom_cat.nbr = cpt_nom_tot ;
  BFT_MALLOC(tab_nom_cat.val, tab_nom_cat.nbr, char *) ;


  /* Préparation */

  cpt_nom_tot = 0 ;

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

    if (vect_fam_tete[ient] != NULL) {

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

        for (iloc = 0 ; iloc < tab_propr_nom_fam_ent[ient][ifam].nbr ; iloc++) {

          tab_nom_cat.val[cpt_nom_tot]
            = tab_propr_nom_fam_ent[ient][ifam].val[iloc] ;

          cpt_nom_tot++ ;

        }

      }

    }

  }


  /* Tri et renumérotation */

  tab_renum.nbr = tab_nom_cat.nbr ;
  BFT_MALLOC(tab_renum.val, tab_renum.nbr,  ecs_int_t) ;

  tab_nom_trie = ecs_tab_char__trie_et_renvoie(tab_nom_cat,
                                               tab_renum) ;

  BFT_FREE(tab_nom_cat.val) ;
  BFT_FREE(tab_renum.val) ;

  tab_nom_cpct = ecs_tab_char__compacte(tab_nom_trie) ;

  BFT_FREE(tab_nom_trie.val) ;


  /* Recopie dans le tableau des noms de groupes ; */

  noms_groupes->nbr = tab_nom_cpct.nbr ;
  BFT_MALLOC(noms_groupes->val, noms_groupes->nbr, char *) ;

  for (ind = 0 ; ind < tab_nom_cpct.nbr ; ind++) {

    BFT_MALLOC(noms_groupes->val[ind], strlen(tab_nom_cpct.val[ind]) + 1, char) ;

    strcpy(noms_groupes->val[ind], tab_nom_cpct.val[ind]) ;

  }

  BFT_FREE(tab_nom_cpct.val) ;

}


Generated by  Doxygen 1.6.0   Back to index