/*============================================================================
*
*                    Code_Saturne version 1.3
*                    ------------------------
*
*
*     This file is part of the Code_Saturne Kernel, element of the
*     Code_Saturne CFD tool.
*
*     Copyright (C) 1998-2007 EDF S.A., France
*
*     contact: saturne-support@edf.fr
*
*     The Code_Saturne Kernel 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 Kernel 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 Kernel; if not, write to the
*     Free Software Foundation, Inc.,
*     51 Franklin St, Fifth Floor,
*     Boston, MA  02110-1301  USA
*
*============================================================================*/

/*============================================================================
 * Interfaces Fortran pour l'échange de messages avec le module Enveloppe
 *============================================================================*/

/* Includes système */

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

/* Includes BFT */

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


/* Includes librairie */

#include "cs_base.h"
#include "cs_comm.h"

#include "cs_maillage.h"
#include "cs_perio.h"

#include "cs_messages_ecs.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */


/*============================================================================
 * Prototypes de fonctions externes publiques
 *============================================================================*/


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


/*============================================================================
 *  Fonctions publiques pour API Fortran
 *============================================================================*/

/*----------------------------------------------------------------------------
 * Définition pour la réception des messages 'dim' issus du Préprocesseur
 *
 * Interface Fortran :
 *
 * SUBROUTINE LEDEVI(NOMRUB, TYPENT, NBRENT, TABENT)
 * *****************
 *
 * INTEGER          NDIM        : <-- : Dimension de l'espace (3)
 * INTEGER          NCELET      : <-- : Nombre d'éléments halo compris
 * INTEGER          NCEL        : <-- : Nombre d'éléments actifs
 * INTEGER          NFAC        : <-- : Nombre de faces internes
 * INTEGER          NFABOR      : <-- : Nombre de faces de bord
 * INTEGER          NFML        : <-- : Nombre de familles des faces de bord
 * INTEGER          NPRFML      : <-- : Nombre de propriétés max par famille
 * INTEGER          NSOM        : <-- : Nombre de sommets (optionnel)
 * INTEGER          LNDFAC      : <-- : Longueur de SOMFAC (optionnel)
 * INTEGER          LNDFBR      : <-- : Longueur de SOMFBR (optionnel)
 * INTEGER          IPERIO      : <-- : Indicateur de périodicité
 * INTEGER          IPEROT      : <-- : Nombre de périodicités de rotation
 *----------------------------------------------------------------------------*/

void CS_PROCF(ledevi, LEDEVI)
(
 cs_int_t   *const ndim,    /* <-- dimension de l'espace                      */
 cs_int_t   *const ncelet,  /* <-- nombre d'éléments halo compris             */
 cs_int_t   *const ncel,    /* <-- nombre d'éléments actifs                   */
 cs_int_t   *const nfac,    /* <-- nombre de faces internes                   */
 cs_int_t   *const nfabor,  /* <-- nombre de faces de bord                    */
 cs_int_t   *const nfml,    /* <-- nombre de familles des faces de bord       */
 cs_int_t   *const nprfml,  /* <-- nombre de propriétés max par famille       */
 cs_int_t   *const nsom,    /* <-- nombre de sommets (optionnel)              */
 cs_int_t   *const lndfac,  /* <-- longueur de somfac (optionnel)             */
 cs_int_t   *const lndfbr,  /* <-- longueur de somfbr (optionnel)             */
 cs_int_t   *const iperio,  /* <-- indicateur de périodicité                  */
 cs_int_t   *const iperot   /* <-- nombre de périodicités de rotation         */
)
{
  cs_comm_msg_entete_t   entete;
  cs_comm_t             *comm = cs_glob_comm_ecs_vers_cs;

  cs_int_t               ind;

  cs_maillage_t         *maillage = cs_glob_maillage;

  const char  *msg_inattendu = N_("Message de type <%s> sur <%s>\n"
                                  "inattendu ou de taille incorrecte");

  cs_bool_t lecdim = CS_FALSE;
  cs_bool_t lecfin = CS_FALSE;

  /* Initialisation des valeurs de retour */

  *ndim = 3;

  *ncel   = 0;
  *ncelet = 0;
  *nfac   = 0;
  *nfabor = 0;
  *nsom   = 0;
  *lndfac = 0;
  *lndfbr = 0;

  *nfml   = 0;
  *nprfml = 0;


  /* Boucle de lecture des messages */

  while (lecfin == CS_FALSE) {

    /* Réception de l'entête et suppression des blancs de fin de nom */

    cs_comm_recoit_entete(&entete, comm);

    for (ind = CS_COMM_LNG_NOM_RUB - 1; entete.nom_rub[ind] == ' '; ind--);
    ind++;
    if (ind < CS_COMM_LNG_NOM_RUB) entete.nom_rub[ind] = '\0';

    /* interprétation des messages "de catégorie" */

    if (entete.num_rub != 0)
      bft_error(__FILE__, __LINE__, 0,
                _("Numéro de rubrique de message <%d> inattendue sur <%s>"),
                entete.num_rub, cs_comm_ret_nom(comm));

    if (strncmp(entete.nom_rub, CS_COMM_FIN_FICHIER, CS_COMM_LNG_NOM_RUB)
        == 0) {
      cs_glob_comm_ecs_vers_cs = cs_comm_termine(comm);
      comm = NULL;
    }

    if (strncmp(entete.nom_rub, "start_block:dimensions",
                CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim == CS_FALSE)
        lecdim = CS_TRUE;
      else
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
    }

    else if (strncmp(entete.nom_rub, "end_block:dimensions",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim == CS_TRUE) {
        lecdim = CS_FALSE;
        lecfin = CS_TRUE;
      }
      else
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
    }


    /* interprétation des messages du bloc dimension */

    else if (strncmp(entete.nom_rub, "ndim",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else
        cs_comm_recoit_corps(&entete, (void *) &(maillage->dim), comm);
    }

    else if (strncmp(entete.nom_rub, "ncel",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        cs_comm_recoit_corps(&entete, (void *) &(maillage->nbr_cel), comm);
        maillage->nbr_cel_glob = maillage->nbr_cel;
      }
    }

    else if (strncmp(entete.nom_rub, "nfac",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        cs_comm_recoit_corps(&entete, (void *) &(maillage->nbr_fac), comm);
        maillage->nbr_fac_glob = maillage->nbr_fac;
      }
    }

    else if (strncmp(entete.nom_rub, "nfabor",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else
        cs_comm_recoit_corps(&entete, (void *) &(maillage->nbr_fbr), comm);
        maillage->nbr_fbr_glob = maillage->nbr_fbr;
    }

    else if (strncmp(entete.nom_rub, "maillage:dim:familles:nbr",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else
        cs_comm_recoit_corps(&entete, (void *) &(maillage->nbr_fam), comm);
    }

    else if (strncmp(entete.nom_rub, "maillage:dim:familles:prop:nbr",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else
        cs_comm_recoit_corps(&entete,
                             (void *) &(maillage->nbr_prop_fam_max), comm);
    }

    else if (strncmp (entete.nom_rub, "maillage:dim:groupes:nbr",
                      CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else
        cs_comm_recoit_corps(&entete, (void *) &(maillage->nbr_grp), comm);
    }

    else if (strncmp(entete.nom_rub, "maillage:dim:nsom",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        cs_comm_recoit_corps(&entete,
                             (void *) &(maillage->nbr_som), comm);
        maillage->nbr_som_glob = maillage->nbr_som;
      }
    }

    else if (strncmp(entete.nom_rub, "lndfac",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else
        cs_comm_recoit_corps(&entete, (void *) &(maillage->lng_fac_som), comm);
    }

    else if (strncmp(entete.nom_rub, "lndfbr",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else
        cs_comm_recoit_corps(&entete, (void *) &(maillage->lng_fbr_som), comm);
    }

    /* interprétation des messages pour le voisinage étendu */

    else if (   strncmp(entete.nom_rub, "maillage:dim:voiset:dom:nval",
                        CS_COMM_LNG_NOM_RUB) == 0
             || strncmp(entete.nom_rub, "lelvse",
                        CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else
        cs_comm_recoit_corps(&entete,
                    (void *) &maillage->nbr_val_connect_voiset_cel_cel_dom, comm);

    }

    /* interprétation des messages pour les dimensions avec parallélisme */

    else if (strncmp(entete.nom_rub, "maillage:dim:nbrdom",
                      CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else
        cs_comm_recoit_corps(&entete, (void *) &(maillage->nbr_dom),comm);
    }

    else if (strncmp(entete.nom_rub, "maillage:dim:ndomfp",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else
        cs_comm_recoit_corps(&entete,
                             (void *) &(maillage->nbr_dom_fac_par), comm);
    }

    else if (strncmp(entete.nom_rub, "maillage:dim:ncelfp",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else
        cs_comm_recoit_corps(&entete,
                             (void *) &(maillage->nbr_cel_fac_par), comm);
    }

    /* interprétation des messages pour les dimensions avec
       voisinage étendu séparé en parallélisme ou périodicité */

    else if (strncmp(entete.nom_rub, "maillage:dim:voiset:ndomfp",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else
        cs_comm_recoit_corps(&entete,
                             (void *) &(maillage->nbr_dom_fac_par_voiset),
                             comm);
    }

    else if (strncmp(entete.nom_rub, "maillage:dim:voiset:ncelfp",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else
        cs_comm_recoit_corps(&entete,
                             (void *) &(maillage->nbr_cel_fac_par_voiset),
                             comm);
    }

    /* interprétation des messages pour les dimensions avec périodicité */
    /* les cellules fantômes pour la périodicité ont été recues avant.  */
    /* On alloue ici la liste des paramètres des périodicités.          */

    else if (strncmp(entete.nom_rub, "maillage:dim:per:nbrtot",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        cs_comm_recoit_corps(&entete, (void *) &(maillage->nbr_per), comm);
        *iperio = 1;
        BFT_MALLOC(maillage->liste_param_per, maillage->nbr_per,
                   cs_param_perio_t);
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:dim:per:nbrrot",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdim != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else
        cs_comm_recoit_corps(&entete, (void *) iperot, comm);
    }

    else
      bft_error(__FILE__, __LINE__, 0,
                _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));

  }

  /* Valeurs calculées */

  maillage->nbr_cel_etendu = maillage->nbr_cel + maillage->nbr_cel_fac_par;

  /* Valeurs de retour */

  *ndim = maillage->dim;

  *ncel   = maillage->nbr_cel;
  *ncelet = maillage->nbr_cel_etendu;
  *nfac   = maillage->nbr_fac;
  *nfabor = maillage->nbr_fbr;
  *nsom   = maillage->nbr_som;
  *lndfac = maillage->lng_fac_som;
  *lndfbr = maillage->lng_fbr_som;

  *nfml   = maillage->nbr_fam;
  *nprfml = maillage->nbr_prop_fam_max;

}

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

/*----------------------------------------------------------------------------
 * Réception des messages du bloc 'data' issus du module Enveloppe
 * puis fermeture de la communication.
 *----------------------------------------------------------------------------*/

void cs_messages_ecs_lit_data
(
 cs_maillage_t      *const maillage       /* <-> maillage associé             */
)
{
  cs_comm_msg_entete_t   entete;
  cs_comm_t             *comm = cs_glob_comm_ecs_vers_cs;

  cs_int_t               ind;
  cs_int_t               ind_per;
  cs_int_t               nbr_elt;
  cs_int_t               typ_per;

  cs_real_t             *lit_vide = NULL;

  const char  *msg_inattendu = N_("Message de type <%s> sur <%s>\n"
                                  "inattendu ou de taille incorrecte");

  cs_bool_t lecfin = CS_FALSE;
  cs_bool_t lecdat = CS_FALSE;

  /* Boucle de lecture des messages */

  while (lecfin == CS_FALSE) {

    /* Réception de l'entête et suppression des blancs de fin de nom */

    cs_comm_recoit_entete(&entete, comm);

    for (ind = CS_COMM_LNG_NOM_RUB - 1 ; entete.nom_rub[ind] == ' ' ; ind--);
    ind++;
    if (ind < CS_COMM_LNG_NOM_RUB) entete.nom_rub[ind] = '\0';

    /* interprétation des messages "de catégorie" */

    if (entete.num_rub != 0)
      bft_error(__FILE__, __LINE__, 0,
                _("Numéro de rubrique de message <%d> inattendue sur <%s>"),
                entete.num_rub, cs_comm_ret_nom(comm));

    if (strncmp(entete.nom_rub, CS_COMM_FIN_FICHIER, CS_COMM_LNG_NOM_RUB)
        == 0) {
      cs_glob_comm_ecs_vers_cs = cs_comm_termine (comm);
      comm = NULL;
    }

    if (strncmp(entete.nom_rub, "start_block:data",
                CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat == CS_FALSE)
        lecdat = CS_TRUE;
      else
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
    }

    else if (strncmp(entete.nom_rub, "end_block:data",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat == CS_TRUE) {
        lecdat = CS_FALSE;
        lecfin = CS_TRUE;
      }
      else
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
    }


    /* interprétation des messages du bloc data */

    else if (strncmp(entete.nom_rub, "ifacel",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      nbr_elt = maillage->nbr_fac * 2;
      if (lecdat != CS_TRUE || entete.nbr_elt != nbr_elt)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->fac_cel, nbr_elt, cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->fac_cel, comm);
      }
    }

    else if (strncmp(entete.nom_rub, "ifabor",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != maillage->nbr_fbr)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->fbr_cel, maillage->nbr_fbr, cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->fbr_cel, comm);
      }
    }

    else if (strncmp(entete.nom_rub, "xyzcen",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      nbr_elt = maillage->dim * maillage->nbr_cel;
      if (lecdat != CS_TRUE || entete.nbr_elt != nbr_elt)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        /* Surdimensionnement pour cellules fantômes */
        nbr_elt = maillage->dim * maillage->nbr_cel_etendu;
        BFT_MALLOC(lit_vide, nbr_elt, cs_real_t);
        cs_comm_recoit_corps(&entete, (void *) lit_vide, comm);
        BFT_FREE(lit_vide);
      }
    }

    else if (strncmp(entete.nom_rub, "surfac",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      nbr_elt = maillage->dim * maillage->nbr_fac;
      if (lecdat != CS_TRUE || entete.nbr_elt != nbr_elt)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(lit_vide, nbr_elt, cs_real_t);
        cs_comm_recoit_corps(&entete, (void *) lit_vide, comm);
        BFT_FREE(lit_vide);
      }
    }

    else if (strncmp(entete.nom_rub, "surfbr",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      nbr_elt = maillage->dim * maillage->nbr_fbr;
      if (lecdat != CS_TRUE || entete.nbr_elt != nbr_elt)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(lit_vide, nbr_elt, cs_real_t);
        cs_comm_recoit_corps(&entete, (void *) lit_vide, comm);
        BFT_FREE(lit_vide);
      }
    }

    else if (strncmp(entete.nom_rub, "cdgfac",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      nbr_elt = maillage->dim * maillage->nbr_fac;
      if (lecdat != CS_TRUE || entete.nbr_elt != nbr_elt)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(lit_vide, nbr_elt, cs_real_t);
        cs_comm_recoit_corps(&entete, (void *) lit_vide, comm);
        BFT_FREE(lit_vide);
      }
    }

    else if (strncmp(entete.nom_rub, "cdgfbr",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      nbr_elt = maillage->dim * maillage->nbr_fbr;
      if (lecdat != CS_TRUE || entete.nbr_elt != nbr_elt)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(lit_vide, nbr_elt, cs_real_t);
        cs_comm_recoit_corps(&entete, (void *) lit_vide, comm);
        BFT_FREE(lit_vide);
      }
    }

    else if (   strncmp(entete.nom_rub, "maillage:data:fbr:famille",
                        CS_COMM_LNG_NOM_RUB) == 0
             || strncmp(entete.nom_rub, "ifafbr",
                        CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != maillage->nbr_fbr)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->fam_fbr, maillage->nbr_fbr, cs_int_t);
        cs_comm_recoit_corps(&entete, (void *) maillage->fam_fbr, comm);
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:data:cel:famille",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != maillage->nbr_cel)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        /* Surdimensionnement pour cellules fantômes */
        BFT_MALLOC(maillage->fam_cel, maillage->nbr_cel_etendu, cs_int_t);
        cs_comm_recoit_corps(&entete, (void *) maillage->fam_cel, comm);
      }
    }

    else if (   strncmp(entete.nom_rub, "maillage:data:familles:propr",
                        CS_COMM_LNG_NOM_RUB) == 0
             || strncmp(entete.nom_rub, "iprfml",
                        CS_COMM_LNG_NOM_RUB) == 0) {
      nbr_elt = maillage->nbr_fam * maillage->nbr_prop_fam_max;
      if (lecdat != CS_TRUE || entete.nbr_elt != nbr_elt)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->prop_fam, nbr_elt, cs_int_t);
        cs_comm_recoit_corps(&entete, (void *) maillage->prop_fam, comm);
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:data:groupes:pos",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != maillage->nbr_grp + 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->pos_grp, maillage->nbr_grp + 1, cs_int_t);
        cs_comm_recoit_corps (&entete, (void *) maillage->pos_grp, comm);
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:data:groupes:noms",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE || maillage->pos_grp == NULL ||
          entete.nbr_elt != maillage->pos_grp[maillage->nbr_grp] - 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->nom_grp, entete.nbr_elt, char);
        cs_comm_recoit_corps (&entete, (void *) maillage->nom_grp, comm);
      }
    }

    else if (   strncmp(entete.nom_rub, "xyznod",
                        CS_COMM_LNG_NOM_RUB) == 0
             || strncmp(entete.nom_rub, "maillage:data:som:xyz",
                        CS_COMM_LNG_NOM_RUB) == 0) {
      nbr_elt = maillage->dim * maillage->nbr_som;
      if (lecdat != CS_TRUE || entete.nbr_elt != nbr_elt)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->coo_som, nbr_elt, cs_real_t);
        cs_comm_recoit_corps (&entete, (void *) maillage->coo_som, comm);
      }
    }

    else if (strncmp(entete.nom_rub, "ipnfac",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      nbr_elt = maillage->nbr_fac + 1;
      if (   lecdat != CS_TRUE
          || maillage->nbr_som == 0 || entete.nbr_elt != nbr_elt)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->pos_fac_som, nbr_elt, cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->pos_fac_som, comm);
      }
    }

    else if (strncmp(entete.nom_rub, "nodfac",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (   lecdat != CS_TRUE
          || maillage->nbr_som == 0 || entete.nbr_elt != maillage->lng_fac_som)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->val_fac_som, maillage->lng_fac_som, cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->val_fac_som, comm);
      }
    }

    else if (strncmp(entete.nom_rub, "ipnfbr",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      nbr_elt = maillage->nbr_fbr + 1;
      if (   lecdat != CS_TRUE
          || maillage->nbr_som == 0 || entete.nbr_elt != nbr_elt)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->pos_fbr_som, nbr_elt, cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->pos_fbr_som, comm);
      }
    }

    else if (strncmp(entete.nom_rub, "nodfbr",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (   lecdat != CS_TRUE
          || maillage->nbr_som == 0 || entete.nbr_elt != maillage->lng_fbr_som)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->val_fbr_som, maillage->lng_fbr_som, cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->val_fbr_som, comm);
      }
    }

    /* Voisinage étendu cellule -> cellules */

    else if (strncmp(entete.nom_rub, "maillage:data:voiset:type",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        cs_comm_recoit_corps(&entete,
                             (void *) &maillage->ind_type_voiset,
                             comm);
#if defined(_CS_HAVE_MPI)
        /* Rien à faire : tout va bien */
#else
        /* Le traitement du voisinage étendu separé si on ne peut pas être en
           parallèle. Normalement, l'Enveloppe ne produit des voisinages
           étendus séparés que si l'on fait un calcul parallèle. Dans ce cas
           on a donc forcément un Noyau compilé en MPI */
        if (maillage->ind_type_voiset == CS_MAILLAGE_TYPE_VOISET_SEPARE)
          bft_error(__FILE__, __LINE__, 0,
                    _("Calcul des gradients avec voisinage étendu séparé "
                      "impossible avec une version du Noyau non compilée avec MPI"));
#endif /*_CS_HAVE_MPI */
      }
    }

    else if (   strncmp(entete.nom_rub, "maillage:data:voiset:dom:pos",
                        CS_COMM_LNG_NOM_RUB) == 0
             || strncmp(entete.nom_rub, "ipcvse",
                        CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != maillage->nbr_cel + 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        /* Selon les options de calcul, s'il est inutile, on pourrait le
           libérer immédiatement après */
        BFT_MALLOC(maillage->pos_connect_voiset_cel_cel_dom, entete.nbr_elt,
                   cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->pos_connect_voiset_cel_cel_dom,
                             comm);
      }
    }

    else if (   strncmp(entete.nom_rub, "maillage:data:voiset:dom:num",
                        CS_COMM_LNG_NOM_RUB) == 0
             || strncmp(entete.nom_rub, "ielvse",
                        CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE ||
          entete.nbr_elt != (maillage->nbr_val_connect_voiset_cel_cel_dom))
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        /* on vérifie la cohérence avec la taille indiquée dans pos */
        assert(maillage->nbr_val_connect_voiset_cel_cel_dom ==
               (maillage->pos_connect_voiset_cel_cel_dom)[maillage->nbr_cel]-1) ;
        BFT_MALLOC(maillage->val_connect_voiset_cel_cel_dom, entete.nbr_elt,
                   cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->val_connect_voiset_cel_cel_dom,
                             comm);
      }
    }

    /* Tableaux supplémentaires pour le parallélisme */

    else if (strncmp(entete.nom_rub, "maillage:data:celfp:dom:pos",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != maillage->nbr_dom_fac_par + 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->pos_dom_fac_par,
                   maillage->nbr_dom_fac_par + 1,
                   cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->pos_dom_fac_par, comm);
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:data:celfp:dom:num",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != maillage->nbr_dom_fac_par)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->num_dom_fac_par,
                   maillage->nbr_dom_fac_par,
                   cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->num_dom_fac_par, comm);
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:data:celfp:num",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != maillage->nbr_cel_fac_par)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->num_cel_fac_par,
                   maillage->nbr_cel_fac_par,
                   cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->num_cel_fac_par,
                             comm);
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:data:cel:num",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != maillage->nbr_cel)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        cs_int_t *recv_buf;
        BFT_MALLOC(maillage->num_cel, maillage->nbr_cel, fvm_gnum_t);
        BFT_MALLOC(recv_buf, maillage->nbr_cel, cs_int_t);
        cs_comm_recoit_corps (&entete, (void *) recv_buf, comm);
        for (ind = 0; ind < maillage->nbr_cel; ind++)
          maillage->num_cel[ind] = recv_buf[ind];
        BFT_FREE(recv_buf);
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:data:fac:num",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != maillage->nbr_fac)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        cs_int_t *recv_buf;
        BFT_MALLOC(maillage->num_fac, maillage->nbr_fac, fvm_gnum_t);
        BFT_MALLOC(recv_buf, maillage->nbr_fac, cs_int_t);
        cs_comm_recoit_corps(&entete, (void *) recv_buf, comm);
        for (ind = 0; ind < maillage->nbr_fac; ind++)
          maillage->num_fac[ind] = recv_buf[ind];
        BFT_FREE(recv_buf);
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:data:fbr:num",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != maillage->nbr_fbr)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        cs_int_t *recv_buf;
        BFT_MALLOC(maillage->num_fbr, maillage->nbr_fbr, fvm_gnum_t);
        BFT_MALLOC(recv_buf, maillage->nbr_fbr, cs_int_t);
        cs_comm_recoit_corps(&entete, (void *) recv_buf, comm);
        for (ind = 0; ind < maillage->nbr_fbr; ind++)
          maillage->num_fbr[ind] = recv_buf[ind];
        BFT_FREE(recv_buf);
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:data:som:num",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != maillage->nbr_som)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        cs_int_t *recv_buf;
        BFT_MALLOC(maillage->num_som, maillage->nbr_som, fvm_gnum_t);
        BFT_MALLOC(recv_buf, maillage->nbr_som, cs_int_t);
        cs_comm_recoit_corps(&entete, (void *) recv_buf, comm);
        for (ind = 0; ind < maillage->nbr_som; ind++)
          maillage->num_som[ind] = recv_buf[ind];
        BFT_FREE(recv_buf);
      }
    }

    /* Tableaux supplémentaires pour le voisinage étendu séparé
       avec parallélisme */

    else if (strncmp(entete.nom_rub, "maillage:data:voiset:celfp:dom:p",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE ||
          entete.nbr_elt != maillage->nbr_dom_fac_par_voiset + 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->pos_dom_fac_par_voiset,
                   maillage->nbr_dom_fac_par_voiset + 1,
                   cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->pos_dom_fac_par_voiset,
                             comm);
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:data:voiset:celfp:dom:n",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE ||
          entete.nbr_elt != maillage->nbr_dom_fac_par_voiset)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->num_dom_fac_par_voiset,
                   maillage->nbr_dom_fac_par_voiset,
                   cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->num_dom_fac_par_voiset,
                             comm);
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:data:voiset:celfp:num",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (lecdat != CS_TRUE ||
          entete.nbr_elt != maillage->nbr_cel_fac_par_voiset)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        maillage->nbr_cel_fac_par_voiset = entete.nbr_elt ;
        BFT_MALLOC(maillage->num_cel_fac_par_voiset,
                   maillage->nbr_cel_fac_par_voiset,
                   cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->num_cel_fac_par_voiset,
                             comm);
      }
    }

    /* Tableaux supplémentaires pour la périodicité */

    else if (strncmp(entete.nom_rub, "maillage:data:per:type:",
                     strlen("maillage:data:per:type:")) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        ind_per = atoi(entete.nom_rub + strlen("maillage:data:per:type:")) - 1;
        maillage->liste_param_per[ind_per].num_perio = ind_per + 1;
        cs_comm_recoit_corps(&entete, (void *) &(typ_per), comm);
        maillage->liste_param_per[ind_per].type_perio
          = (cs_perio_typ_t) typ_per;
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:data:per:trans:",
                     strlen("maillage:data:per:trans:")) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != maillage->dim)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        ind_per = atoi(entete.nom_rub + strlen("maillage:data:per:trans:")) - 1;
        cs_comm_recoit_corps(&entete,
                        (void *) maillage->liste_param_per[ind_per].translation,
                             comm);
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:data:per:ptinv:",
                     strlen("maillage:data:per:ptinv:")) == 0) {
      if (lecdat != CS_TRUE || entete.nbr_elt != maillage->dim)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        ind_per = atoi(entete.nom_rub + strlen("maillage:data:per:ptinv:")) - 1;
        cs_comm_recoit_corps(&entete,
                        (void *) maillage->liste_param_per[ind_per].point_inv,
                             comm);
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:data:per:matrice:",
                     strlen("maillage:data:per:matrice:")) == 0) {
      nbr_elt = maillage->dim * maillage->dim;
      if (lecdat != CS_TRUE || entete.nbr_elt != nbr_elt)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        ind_per = atoi(entete.nom_rub
                       + strlen("maillage:data:per:matrice:")) - 1;
        cs_comm_recoit_corps(&entete,
                       (void *) maillage->liste_param_per[ind_per].matrice,
                             comm);
      }
    }

    else if (strncmp(entete.nom_rub, "maillage:data:celfp:per:pos",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (   lecdat != CS_TRUE
          || entete.nbr_elt
             != (2*maillage->nbr_per + 1)*maillage->nbr_dom_fac_par + 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->pos_per_fac_par,
                   (2*maillage->nbr_per + 1) * maillage->nbr_dom_fac_par + 1,
                   cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->pos_per_fac_par, comm);
      }
    }

    /* Tableaux supplémentaires pour le voisinage étendu séparé avec
       périodicité */

    else if (strncmp(entete.nom_rub, "maillage:data:voiset:celfp:per:pos",
                     CS_COMM_LNG_NOM_RUB) == 0) {
      if (   lecdat != CS_TRUE
          || entete.nbr_elt
             != (2*maillage->nbr_per + 1)*maillage->nbr_dom_fac_par_voiset + 1)
        bft_error(__FILE__, __LINE__, 0,
                  _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));
      else {
        BFT_MALLOC(maillage->pos_per_fac_par_voiset,
                   (2*maillage->nbr_per + 1)*maillage->nbr_dom_fac_par_voiset+1,
                   cs_int_t);
        cs_comm_recoit_corps(&entete,
                             (void *) maillage->pos_per_fac_par_voiset, comm);
      }
    }

    else
      bft_error(__FILE__, __LINE__, 0,
                _(msg_inattendu), entete.nom_rub, cs_comm_ret_nom(comm));

  }


  /* Terminaison de la communication avec l'Enveloppe */
  /*--------------------------------------------------*/

  if (cs_glob_comm_ecs_vers_cs != NULL) {
    cs_comm_termine(cs_glob_comm_ecs_vers_cs);
    cs_glob_comm_ecs_vers_cs = NULL;
  }


  /* Renumérotation des sommets dans le cas parallèle (la numérotation
     globale fournie par l'Enveloppe n'étant pas nécessairement croissante) */

  if (maillage->num_som != NULL)
    cs_maillage_ordonne_sommets(maillage);

}


#ifdef __cplusplus
}
#endif /* __cplusplus */

