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

ecs_champ_post_cgns.c

/*============================================================================
 *  Définitions des fonctions
 *   associées à la structure `ecs_champ_t' décrivant un champ
 *   et réalisant les sorties pour post-traitement CGNS
 *============================================================================*/

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

#include "ecs_config.h"

#if defined(HAVE_CGNS)

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

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

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

#include <cgnslib.h>

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


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

#include "ecs_def.h"
#include "ecs_elt_typ_liste.h"
#include "ecs_fic.h"


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

#include "ecs_post.h"
#include "ecs_post_cgns.h"


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

#include "ecs_cgns_def.h"


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

#include "ecs_champ.h"


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

#include "ecs_post_cgns.h"
#include "ecs_champ_post_cgns.h"


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

#include "ecs_cgns_priv.h"
#include "ecs_champ_priv.h"


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

/*----------------------------------------------------------------------------
 *  Fonction qui renvoie un pointeur sur une sous-structure associée
 *  à un maillage pour un cas de sortie CGNS.
 *---------------------------------------------------------------------------*/

static ecs_cgns_base_t  * ecs_loc_champ_post_cgns__base
(
 const ecs_cgns_t  *const cas_cgns,
 const char        *const nom_maillage
) ;


/*----------------------------------------------------------------------------
 *  Fonction d'extraction des numéros de familles
 *---------------------------------------------------------------------------*/

static ecs_tab_int_t ecs_loc_champ_post_cgns__famille
(
 const ecs_champ_t  *const champ_def,
       ecs_champ_t  *const champ_famille
) ;


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

/*----------------------------------------------------------------------------
 *  Fonction qui écrit les connectivités nodales des éléments
 *   selon leur type géometrique
 *
 *  Les élements doivent avoir été triés suivant leur type géometrique,
 *  et les polyèdres sont ignorés.
 *---------------------------------------------------------------------------*/

void ecs_champ_post_cgns__ecr_connect
(
 const char           *const nom_maillage,
       ecs_champ_t    *const champ_som,
       ecs_champ_t    *const champ_def,
       ecs_champ_t    *const champ_famille,
 const ecs_tab_int_t  *const tab_elt_typ_geo,
       ecs_cgns_t     *const cas_cgns
)
{

  size_t     ielt ;
  size_t     ival ;
  size_t     ival_deb ;
  size_t     isom ;
  int        icoo ;
  ecs_int_t  ind ;
  ecs_int_t  ind_typ ;

  size_t     cpt_elt ;
  size_t     cpt_elt_fin ;
  size_t     nbr_coo ;
  size_t     nbr_elt ;
  size_t     nbr_som ;
  size_t     nbr_som_elt ;
  size_t     nbr_val ;
  int        elt_typ_ref ;

  ecs_bool_t  bool_single ;

  ecs_size_t * def_pos_tab ;
  ecs_int_t  * def_val_tab ;

  ecs_real_t * som_val_tab ;

  ecs_tab_int_t  tab_famille ;

  int         cpt_section ;
  size_t      nbr_elt_typ ;
  int         isize[3] ;
  int         num_coord ;
  int         num_section ;
  int         num_zone ;
  int         ret_cgns ;

  int         type_cgns[ECS_ELT_TYP_FIN] ;
  int         type_cgns_loc ;

  int        *def_elt ;

  double     *coo_temp ;

  char        nom_section[32 + 1] ;

  char const  *nom_coord[3] = {"CoordinateX",
                               "CoordinateY",
                               "CoordinateZ"} ;

  ecs_cgns_base_t  *base_cgns ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(champ_som != NULL) ;
  assert(champ_def != NULL) ;

  assert(cas_cgns != NULL) ;


  /* Recherche de la base CGNS */
  /*---------------------------*/

  base_cgns = ecs_loc_champ_post_cgns__base(cas_cgns,
                                            nom_maillage) ;


  /* Dimensions */
  /*------------*/

  nbr_som = champ_som->nbr_elt ;
  nbr_elt = champ_def->nbr_elt ;

  isize[0] = nbr_som ;
  isize[1] = nbr_elt - tab_elt_typ_geo->val[ECS_ELT_TYP_CEL_POLY];

  isize[2] = 0 ;       /* éléments de bord non triés */

  ret_cgns = cg_zone_write(base_cgns->num_fic,
                           1,
                           "Zone 1",
                           isize,
                           Unstructured,
                           &num_zone) ;

  if (ret_cgns != CG_OK)
    bft_error(__FILE__, __LINE__, 0,
              _("CGNS: error writing file \"%s\":\n"
                "Name of mesh to write: \"%s\"\n%s"),
              base_cgns->nom_fic, base_cgns->nom_maillage, cg_get_error()) ;

  assert (num_zone == 1) ;


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

  /* récupération des coordonnées et vérifications */

  assert(champ_som->pos_pas == 2 || champ_som->pos_pas == 3) ;
  assert(champ_som->typ_val == ECS_TYPE_ecs_real_t) ;

  nbr_coo = champ_som->pos_pas ;
  som_val_tab = (ecs_real_t *)(champ_som->val_tab) ;

  /* Remplissage du tableau temporaire et écriture */

  BFT_MALLOC(coo_temp, nbr_som, double) ;

  for (icoo = 0 ; icoo < base_cgns->dim_espace ; icoo++) {

    for (isom = 0 ; isom < nbr_som ; isom++)
      coo_temp[isom] = som_val_tab[isom * nbr_coo + icoo] ;

    ret_cgns = cg_coord_write(base_cgns->num_fic,
                              1,
                              1,
                              RealDouble,
                              nom_coord[icoo],
                              coo_temp,
                              &num_coord) ;

    if (ret_cgns != CG_OK)
      bft_error(__FILE__, __LINE__, 0,
                _("CGNS: error writing coordinates\n"
                  "Name of mesh to write: \"%s\"\n%s"),
                base_cgns->nom_maillage, cg_get_error()) ;

  }

  BFT_FREE(coo_temp) ;


  /* Écriture des éléments */
  /*------------------------*/

  bool_single = cas_cgns->single ;

  def_pos_tab =              ecs_champ__ret_pos_tab(champ_def) ;
  def_val_tab = (ecs_int_t *)(champ_def->val_tab) ;

  cpt_section = 0 ;

  cpt_elt = 0 ;

  elt_typ_ref = -1 ;

  for (ind_typ = ECS_ELT_TYP_NUL ; ind_typ < ECS_ELT_TYP_FIN ; ind_typ++)
    type_cgns[ind_typ] = -2 ;

  type_cgns[ECS_ELT_TYP_NUL] = -1 ;
  type_cgns[ECS_ELT_TYP_SOM] = NODE ;
  type_cgns[ECS_ELT_TYP_ARE] = BAR_2 ;
  type_cgns[ECS_ELT_TYP_FAC_TRIA] = TRI_3 ;
  type_cgns[ECS_ELT_TYP_FAC_QUAD] = QUAD_4 ;
  type_cgns[ECS_ELT_TYP_CEL_TETRA] = TETRA_4 ;
  type_cgns[ECS_ELT_TYP_CEL_PYRAM] = PYRA_5 ;
  type_cgns[ECS_ELT_TYP_CEL_PRISM] = PENTA_6 ;
  type_cgns[ECS_ELT_TYP_CEL_HEXA] = HEXA_8 ;
  type_cgns[ECS_ELT_TYP_FAC_POLY] = NGON_n ;
  type_cgns[ECS_ELT_TYP_CEL_POLY] = - 1 ;

#if defined(DEBUG) && !defined(NDEBUG)
  for (ind_typ = ECS_ELT_TYP_NUL ; ind_typ < ECS_ELT_TYP_FIN ; ind_typ++)
    assert(type_cgns[ind_typ] != -2) ;
#endif


  while (cpt_elt < nbr_elt) {

    /* Recherche du prochain type d'élément utilisé */

    elt_typ_ref += 1 ;

    while (tab_elt_typ_geo->val[elt_typ_ref] == 0)
      elt_typ_ref++ ;

    nbr_elt_typ = tab_elt_typ_geo->val[elt_typ_ref] ;
    cpt_elt_fin = cpt_elt + nbr_elt_typ ;


    if (bool_single == ECS_TRUE && cpt_elt == 0) {

      if (nbr_elt_typ == nbr_elt)
        bool_single = ECS_FALSE ;

      else {

        ind = 0 ;
        nbr_val = (def_pos_tab[nbr_elt] - def_pos_tab[0]) + nbr_elt ;

        BFT_MALLOC(def_elt, nbr_val, int) ;

      }

    }

    /* Création des connectivités */
    /*----------------------------*/

    if (bool_single == ECS_FALSE) {
      ind = 0 ;
      nbr_val = def_pos_tab[cpt_elt_fin] - def_pos_tab[cpt_elt] ;
    }

    if (   elt_typ_ref != ECS_ELT_TYP_FAC_POLY
        && elt_typ_ref != ECS_ELT_TYP_CEL_POLY) {

      const ecs_int_t  * num_som_cgns
        = (const ecs_int_t *)ecs_cgns_elt_liste_c
                               [type_cgns[elt_typ_ref]].num_som ;

      type_cgns_loc = type_cgns[elt_typ_ref] ;

      if (bool_single == ECS_FALSE) {
        BFT_MALLOC(def_elt, nbr_val, int) ;
      }

      for (ielt = cpt_elt ; ielt < cpt_elt_fin ; ielt++) {

        ival_deb = def_pos_tab[ielt] - 1 ;

        nbr_som_elt = def_pos_tab[ielt + 1] - def_pos_tab[ielt] ;

        if (bool_single == ECS_TRUE)
          def_elt[ind++] = type_cgns_loc ;

        for (isom = 0 ; isom < nbr_som_elt ; isom++)
          def_elt[ind++] = def_val_tab[ival_deb + num_som_cgns[isom] - 1] ;

      }

    }
    else if (elt_typ_ref == ECS_ELT_TYP_FAC_POLY) { /* Cas des polygones */

      type_cgns_loc = MIXED ;

      if (bool_single == ECS_FALSE) {
        BFT_MALLOC(def_elt, nbr_val + cpt_elt_fin - cpt_elt, int) ;
      }

      for (ielt = cpt_elt ; ielt < cpt_elt_fin ; ielt++) {

        def_elt[ind++] =    def_pos_tab[ielt + 1]
                          - def_pos_tab[ielt]
                          + NGON_n ;

        for (ival = def_pos_tab[ielt    ] - 1 ;
             ival < def_pos_tab[ielt + 1] - 1 ;
             ival++)
          def_elt[ind++] = def_val_tab[ival] ;

      }

    }

    else { /* Cas des polyèdres (ignorés) */

      base_cgns->nbr_polyedres = nbr_elt_typ ;

      cpt_elt += nbr_elt_typ ;

      ecs_warn() ;
      bft_printf(_("CGNS: in mesh: \"%s\",\n"
                   "%d polyhedral cells are ignored.\n"),
                 base_cgns->nom_maillage, nbr_elt_typ) ;

      break ;

    }

    if (bool_single == ECS_FALSE) {

      /* Écriture de la section (sections séparées) */

      cpt_section += 1 ;
      sprintf(nom_section, "Section %2d", cpt_section) ;

      ret_cgns = cg_section_write(base_cgns->num_fic,
                                  1,
                                  1,
                                  nom_section,
                                  type_cgns_loc,
                                  (int)(cpt_elt + 1),
                                  (int)(cpt_elt + nbr_elt_typ),
                                  0,
                                  def_elt,
                                  &num_section) ;

      BFT_FREE(def_elt) ;

    }


    /* On s'apprête à passer au type d'élément suivant */

    cpt_elt += nbr_elt_typ ;

  }

  if (bool_single == ECS_TRUE) {

    /* Écriture de la section (si mixte) */

    cpt_section += 1 ;
    sprintf(nom_section, "Section %2d", cpt_section) ;

    ret_cgns = cg_section_write(base_cgns->num_fic,
                                1,
                                1,
                                nom_section,
                                MIXED,
                                (int)(cpt_elt + 1),
                                (int)(cpt_elt + nbr_elt),
                                0,
                                def_elt,
                                &num_section) ;

    BFT_FREE(def_elt) ;

  }


  /* Nettoyage avant la sortie */
  /*---------------------------*/

  ecs_champ__libere_pos_tab(champ_def, def_pos_tab) ;


  /* Familles des éléments */
  /*-----------------------*/

  tab_famille = ecs_loc_champ_post_cgns__famille(champ_def,
                                                 champ_famille) ;

  ecs_champ_post_cgns__ecr_val(&tab_famille,
                               nom_maillage,
                               _("Family"),
                               cas_cgns) ;

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

}


/*----------------------------------------------------------------------------
 *  Fonction qui écrit les valeurs par élément pour un tableau donné.
 *  Les valeurs correspondant aux polyèdres sont ignorées
 *---------------------------------------------------------------------------*/

void ecs_champ_post_cgns__ecr_val
(
 const ecs_tab_int_t  *const tab_val,
 const char           *const nom_maillage,
 const char           *const nom_champ,
       ecs_cgns_t     *const cas_cgns
)
{

  ecs_cgns_base_t  *base_cgns ;


  /* Declarations des variables pour CGNS */
  /*-------------------------------------*/

  char               nom_champ_cgns[ECS_CGNS_TAILLE_NOM + 1] ;

  DataType_t         type_val_cgns ;

  int                num_sol ;
  int                num_champ ;
  int                ret_cgns ;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(tab_val != NULL) ;


  /* Recherche de la base CGNS */
  /*---------------------------*/

  base_cgns = ecs_loc_champ_post_cgns__base(cas_cgns,
                                            nom_maillage) ;

  if (base_cgns == NULL)
    return ;


  /* Ajout d'une solution au cas CGNS si nécessaire */
  /*------------------------------------------------*/

  if (base_cgns->num_sol_stat < 0) {

    if (cg_sol_write(base_cgns->num_fic,
                     1,
                     1,
                     _("Mesh_values"),
                     CellCenter,
                     &num_sol) != CG_OK)

      bft_error(__FILE__, __LINE__, 0,
                _("CGNS: error writing a solution node\n"
                  "File name: \"%s\" ; base : \"1\"\n%s"),
                base_cgns->nom_fic, cg_get_error()) ;

    base_cgns->num_sol_stat = num_sol;

  }


  /* Nom du champ */

  strncpy(nom_champ_cgns, nom_champ, ECS_CGNS_TAILLE_NOM) ;
  nom_champ_cgns[ECS_CGNS_TAILLE_NOM] = '\0' ;


  /* Écriture du champ */
  /*-------------------*/

  assert(sizeof(ecs_int_t) == sizeof(int)) ;

  type_val_cgns = Integer ;

  if (tab_val->nbr > 0) {

    ret_cgns = cg_field_write(base_cgns->num_fic,
                              1,
                              1,
                              base_cgns->num_sol_stat,
                              type_val_cgns,
                              nom_champ_cgns,
                              (void *)tab_val->val,
                              &num_champ) ;

    if (ret_cgns != CG_OK)
      bft_error(__FILE__, __LINE__, 0,
                _("CGNS: error writing field \"%s\"\n%s"),
                nom_champ_cgns, cg_get_error()) ;

  }

}


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

/*----------------------------------------------------------------------------
 *  Fonction qui renvoie un pointeur sur une sous-structure associée
 *  à un maillage pour un cas de sortie CGNS.
 *---------------------------------------------------------------------------*/

static ecs_cgns_base_t  * ecs_loc_champ_post_cgns__base
(
 const ecs_cgns_t  *const cas_cgns,
 const char        *const nom_maillage
)
{

  ecs_int_t  ind ;

  ecs_cgns_base_t  *base_cgns = NULL ;


  /* Recherche du maillage */
  /*-----------------------*/

  for (ind = 0 ; ind < cas_cgns->nbr_bases ; ind++) {
    base_cgns = cas_cgns->tab_bases[ind] ;
    if (strcmp(nom_maillage, base_cgns->nom_maillage) == 0)
      break ;
  }

  if (ind >= cas_cgns->nbr_bases)
    bft_error(__FILE__, __LINE__, 0,
              _("CGNS: no mesh named \"%s\".\n"
                "is associated to file: \"%s\"\n"),
              nom_maillage, base_cgns->nom_fic);


  /* Réouverture du fichier associé si nécessaire */

  if (base_cgns->fic_ouvert == ECS_FALSE) {

    if (cg_open(base_cgns->nom_fic, MODE_MODIFY, &(base_cgns->num_fic))
        != CG_OK)
      bft_error(__FILE__, __LINE__, 0,
                _("CGNS: error re-opening file \"%s\":\n%s"),
                base_cgns->nom_fic, cg_get_error());

    base_cgns->fic_ouvert = ECS_TRUE ;

  }

  return  base_cgns ;

}


/*----------------------------------------------------------------------------
 *  Fonction d'extraction des numéros de familles
 *---------------------------------------------------------------------------*/

static ecs_tab_int_t ecs_loc_champ_post_cgns__famille
(
 const ecs_champ_t  *const champ_def,
       ecs_champ_t  *const champ_famille
)
{

  size_t  ielt ;
  size_t  pos_elt ;
  size_t  pos_elt_sup ;

  ecs_size_t * famille_pos_tab ;
  ecs_int_t  * famille_val_tab ;

  ecs_tab_int_t  tab_fam ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /* Familles des éléments */
  /*-----------------------*/

  tab_fam.nbr = champ_def->nbr_elt ;
  BFT_MALLOC(tab_fam.val, tab_fam.nbr, ecs_int_t) ;


  if (champ_famille != NULL) {

    famille_val_tab = (ecs_int_t *)(champ_famille->val_tab) ;

    if (champ_famille->pos_pas != 1) {

      /* Certains éléments n'ont pas de famille */

      /* On attribue aux éléments qui n'ont pas de famille, */
      /*  le numéro de famille `0'                          */

      famille_pos_tab = ecs_champ__ret_pos_tab(champ_famille) ;

      for (ielt = 0 ; ielt < tab_fam.nbr ; ielt++) {

        pos_elt     = famille_pos_tab[ielt    ] - 1 ;
        pos_elt_sup = famille_pos_tab[ielt + 1] - 1 ;

        if (pos_elt == pos_elt_sup) {

          tab_fam.val[ielt] = 0 ;

        }
        else {

          tab_fam.val[ielt] = famille_val_tab[pos_elt] ;

        }

      } /* Fin : boucle sur les elements */

      ecs_champ__libere_pos_tab(champ_famille, famille_pos_tab) ;

    }
    else { /* Tous les elements ont une famille */

      for (ielt = 0 ; ielt < tab_fam.nbr ; ielt++)
        tab_fam.val[ielt] = famille_val_tab[ielt] ;

    }

  }
  else { /* Aucun element n'a de famille */

    /* On attribue a tous les elements la famille `0' */

    for (ielt = 0 ; ielt < tab_fam.nbr ; ielt++)
      tab_fam.val[ielt] = 0 ;

  }


  return tab_fam ;

}


#endif /* HAVE_CGNS */

Generated by  Doxygen 1.6.0   Back to index