Concepts et fonctionnalités avancés sur les maillages

Créer et lire dans un maillage des éléments de type polygones et polyèdres quelconques

Créer et lire un maillage avec gestion des profils sur les entités

Créer et lire un maillage évolutif

Créer et lire une équivalence entre les entités d'un maillage

Créer et lire un maillage avec des éléments de structure

Ecriture et lecture en parallèle par la décomposition de domaine

Créer et lire dans un maillage des éléments de type polygones et polyèdres quelconques

En plus des types géométriques prédéfinis (exemples : MED_SEG2, MED_SEG3, MED_TRIA3, ...), il est possible de définir dans un maillage non structuré des éléments qui correspondent à des polygones (mailles ou faces) ou des polyèdres (mailles) quelconques.

Pour décrire la géométrie et la connectivité des mailles/faces polygones quelconques, il s'agit d'adopter la convention suivante. L'ordre de stockage des polygones est libre -i.e. n'est pas régi par l'ordre des types géométriques (donné par le nombre de sommets). Par exemple, si on a 2 polygones à 5 sommets (P5) et 1 polygone à 6 sommets (P6), on peut stocker la connectivité de ces éléments dans l'ordre suivant : P5, P6, P5. On accède à la connectivité de chaque polygone par l'intermédiaire d'un tableau d'indexation. Pour notre exemple cela revient à avoir les 2 tableaux suivants (les indexations dans MED débutent par convention à l'indice 1) :

exemple_connectivite_polygones.png

En connectivité nodale, les entiers stockés dans le tableau de connectivité correspondent à des numéros de noeuds alors qu'en connectivité descendante, ils correspondent à des numéros d'arêtes.

L'écriture de la connectivité des polygones d'un maillage s'appuie sur une routine dédiée MEDmeshPolygonWr / mmhpgw qui prend en paramètres les tableaux d'indexation et de connectivité. A noter que le seul mode de stockage possible du tableau de connectivité est le mode non entrelacé.

/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 *  Use case 13 : a 2D unstructured mesh with 10 nodes and 2 polygons
 * poly1 : 1,4,7,9,6,3
 * poly2 : 2,5,8,10,7,4
 *      9   10
 *
 *   6    7    8
 *
 *   3    4    5
 *
 *      1     2
 *
*/

#include <med.h>
#define MESGERR 1
#include <med_utils.h>

#include <string.h>

int main (int argc, char **argv) {
  med_idt fid;
  const char meshname[MED_NAME_SIZE+1] = "2D unstructured mesh";
  const med_int spacedim = 2;
  const med_int meshdim = 2;
  /*                                         12345678901234561234567890123456 */
  const char axisname[2*MED_SNAME_SIZE+1] = "x               y               ";
  const char unitname[2*MED_SNAME_SIZE+1] = "cm              cm              ";
  /* Dix noeuds dont deux communs aux deux polygones */
  const med_float coordinates[2*10] = { 0.5,   0.,
                                        1.5,   0.,
                                        0.,    0.5,
                                        1.,    0.5,
                                        2.,    0.5,
                                        0.,    1.,
                                        1.,    1.,
                                        2.,    1.,
                                        0.5,   2.,
                                        1.5,   2. };
  const med_int nnodes = 10;
  const med_int indexsize = 3;
  const med_int index[3] = {1,7,13};
  /* connectivity : 2 hexagons */
  const med_int connectivity[12] = {1,4,7,9,6,3,
                                    2,5,8,10,7,4};
  int ret=-1;

  /* open MED file */
  fid = MEDfileOpen("UsesCase_MEDmesh_13.med",
                    MED_ACC_CREAT);
  if (fid < 0) {
    MESSAGE("ERROR : file creation ...");
    goto ERROR;
  }

  /* write a comment in the file */
  if (MEDfileCommentWr(fid,
                       "A 2D unstructured mesh : 12, 12 polygons") < 0) {
    MESSAGE("ERROR : write file description ...");
    goto ERROR;
  }
  
  /* mesh creation : a 2D unstructured mesh */
  if (MEDmeshCr(fid, 
                meshname, 
                spacedim, 
                meshdim, 
                MED_UNSTRUCTURED_MESH, 
                "A 2D mesh with 2 polygons",
                "",
                MED_SORT_DTIT,
                MED_CARTESIAN, 
                axisname, 
                unitname) < 0) {
    MESSAGE("ERROR : mesh creation ...");
    goto ERROR;
  }

  /* nodes coordinates in a cartesian axis in full interlace mode 
     (X1,Y1, X2,Y2, X3,Y3, ...) with no iteration and computation step 
  */
  if (MEDmeshNodeCoordinateWr(fid, 
                              meshname, 
                              MED_NO_DT, 
                              MED_NO_IT, 
                              MED_UNDEF_DT,
                              MED_FULL_INTERLACE, 
                              nnodes, 
                              coordinates) < 0) {
    MESSAGE("ERROR : nodes coordinates ...");
    goto ERROR;
  }

  /* cells connectiviy is defined in nodal mode */
  /* 2 polygons */
  if (MEDmeshPolygonWr(fid,
                       meshname,
                       MED_NO_DT,
                       MED_NO_IT,
                       MED_UNDEF_DT,
                       MED_CELL,
                       MED_NODAL,
                       indexsize,
                       index,
                       connectivity) < 0) {
    MESSAGE("ERROR : polygon connectivity ...");
    goto ERROR;
  }


  /* create family 0 : by default, all mesh entities family number is 0 */
  if (MEDfamilyCr(fid, 
                  meshname,
                  MED_NO_NAME, 
                  0, 
                  0, 
                  MED_NO_GROUP) < 0) {
    MESSAGE("ERROR : family 0 creation ...");
    goto ERROR;
  }

  ret=0;
 ERROR:
  
  /* close MED file */
  if (MEDfileClose(fid)  < 0) {
    MESSAGE("ERROR : close file ...");
    ret=-1;
  }

  return ret;
}

La lecture de la connectivité des polygones d'un maillage demande une approche spécifique. Il est d'abord nécessaire d'appeler 2 fois la routine MEDmeshnEntity / mmhnme. Le premier appel permet de récupérer la taille du tableau d'indexation (le nombre de polygone présent dans le maillage est égal à la taille de ce tableau -1). Le second appel permet de lire la taille du tableau de connectivité qu'il est nécessaire d'allouer en mémoire. Enfin la routine MEDmeshPolygonRd / mmhpgr va lire les tableaux d'indexation et de connectivité.

Le cas d'utilisation suivant montre comment lire la connectivité des polygones d'un maillage.

/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 *  Use case 14 : read a 2D unstructured mesh with 2 polygons
 */

#include <med.h>
#define MESGERR 1
#include <med_utils.h>

#include <string.h>

int main (int argc, char **argv) {
  med_idt fid;
  const char meshname[MED_NAME_SIZE+1] = "2D unstructured mesh";
  char meshdescription[MED_COMMENT_SIZE+1]="";
  med_int meshdim;
  med_int spacedim;
  med_sorting_type sortingtype;
  med_int nstep;
  med_mesh_type meshtype;
  med_axis_type axistype;
  char axisname[2*MED_SNAME_SIZE+1]="";
  char unitname[2*MED_SNAME_SIZE+1]="";
  char dtunit[MED_SNAME_SIZE+1]="";
  med_float *coordinates = NULL;
  med_int nnodes = 0;
  med_int npoly = 0;
  med_int indexsize;
  med_int *index = NULL;
  med_int *connectivity = NULL;
  med_int connectivitysize;
  med_bool coordinatechangement;
  med_bool geotransformation;
  int i;
  int k,ind1,ind2;
  int ret=-1;

  /* open MED file with READ ONLY access mode */
  fid = MEDfileOpen("UsesCase_MEDmesh_13.med",MED_ACC_RDONLY);
  if (fid < 0) {
    MESSAGE("ERROR : open file in READ ONLY ACCESS mode ...");
    goto ERROR;
  }

  /* 
   * ... we know that the MED file has only one mesh, 
   * a real code working would check ... 
   */

  /* read mesh informations : mesh dimension, space dimension ... */
  if (MEDmeshInfoByName(fid, meshname, &spacedim, &meshdim, &meshtype, meshdescription, 
                        dtunit, &sortingtype, &nstep, &axistype, axisname, unitname) < 0) {
    MESSAGE("ERROR : mesh info ...");
    goto ERROR;
  }

  /* read how many nodes in the mesh */
  if ((nnodes = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_NODE, MED_POINT1,
                               MED_COORDINATE, MED_NO_CMODE,&coordinatechangement,
                               &geotransformation)) < 0) {
    MESSAGE("ERROR : number of nodes ...");
    goto ERROR;
  }
  
  /* 
   * ... we know that we only have MED_POLYGON celles in the mesh, 
   * a real code working would check all MED geometry cell types ... 
   */

  /* How many polygon in the mesh in nodal connectivity mode */
  /* For the polygons, we get the size of array index */
  if ((indexsize = MEDmeshnEntity(fid,meshname,MED_NO_DT,MED_NO_IT,
                                  MED_CELL,MED_POLYGON,MED_INDEX_NODE,MED_NODAL,
                                  &coordinatechangement,
                                  &geotransformation)) < 0) {
    MESSAGE("ERROR : read number of polygon ...");
    goto ERROR;
  }
  npoly = indexsize-1;

  /* how many nodes for the polygon connectivity ? */
  if ((connectivitysize = MEDmeshnEntity(fid,meshname,MED_NO_DT,MED_NO_IT,
                                         MED_CELL,MED_POLYGON,MED_CONNECTIVITY,MED_NODAL,
                                         &coordinatechangement,
                                         &geotransformation)) < 0) {
    MESSAGE("ERROR : read connevity size ...");
    goto ERROR;
    }

  /* read mesh nodes coordinates */
  if ((coordinates = (med_float*) malloc(sizeof(med_float)*nnodes*spacedim)) == NULL) {
    MESSAGE("ERROR : memory allocation ...");
    goto ERROR;
  }

  if (MEDmeshNodeCoordinateRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_FULL_INTERLACE,
                              coordinates) < 0) {
    MESSAGE("ERROR : nodes coordinates ...");
    free(coordinates);
    goto ERROR;
  }
  free(coordinates);

  /* read polygons connectivity */
  index = (med_int *) malloc(sizeof(med_int)*indexsize);
  connectivity = (med_int *) malloc(sizeof(med_int)*connectivitysize);

  if (MEDmeshPolygonRd(fid,meshname,MED_NO_DT,MED_NO_IT,MED_CELL,MED_NODAL,
                       index,connectivity) < 0) {
    MESSAGE("ERROR : read polygon connectivity ...");
    free(index);
    free(connectivity);
    goto ERROR;
  }
  free(index);
  free(connectivity);
  
  /* 
   * ... we know that the family number of nodes and elements is 0, a real working would check ...
   */

  ret=0;
 ERROR:

  /* close MED file */
  if (MEDfileClose(fid) < 0) {
    MESSAGE("ERROR : close file");             
    ret=-1; 
  } 

  return ret;
}

Pour décrire la géométrie et la connectivité des mailles polyèdres quelconques, il s'agit d'adopter la convention suivante. Pour la connectivité nodale, on accède à la connectivité via un système de double indexation : un premier tableau d'indexation "indexp" renvoie à la liste des faces de chaque polyèdre ; un second tableau "indexf" renvoie pour chaque face à la liste des noeuds la composant. Voici un exemple d'illustration pour définir la connectivité de "n" polyèdres en mode nodal :

exemple_connectivite_nodale_polyedres.png

A noter que les faces communes sont décrites 2 fois (mêmes listes de noeuds mais orientations différentes) et la normale des faces doit être extérieure.


Pour la connectivité descendante, un seul niveau d'indexation suffit (indexp). Le tableau des connectivités contient les numéros des faces. Le tableau "indexf" contient alors le type géométrique de chaque face (exemple : MED_TRIA3). A noter que dans ce cas, "nf = consiz".

Voici un exemple d'illustration :

exemple_connectivite_descendante_polyedres.png



L'écriture de la connectivité des polyèdres d'un maillage s'appuie sur une routine dédiée MEDmeshPolyhedronWr / mmhphw qui prend en paramètres les tableaux d'indexation et de connectivité. A noter que le seul mode de stockage possible du tableau de connectivité est le mode non entrelacé.

L'exemple suivant propose l'écriture de la connectivité de mailles polyèdres selon les deux modes de connectivité possibles. A noter qu'au même titre que les autres entités d'un maillage, les polyèdres (tout comme les polygones) portent un numéro de famille (0 par défaut) et peuvent porter un nom ou un numéro optionnel.

/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */


/******************************************************************************
 * - Nom du fichier : test25.c
 *
 * - Description : ecriture de mailles de type MED_POLYEDRE
 *                 dans un maillage MED
 *
 *****************************************************************************/

#include <med.h>
#define MESGERR 1
#include <med_utils.h>

#ifdef DEF_LECT_ECR
#define MODE_ACCES MED_ACC_RDWR
#elif DEF_LECT_AJOUT
#define MODE_ACCES MED_ACC_RDEXT
#else
#define MODE_ACCES MED_ACC_CREAT
#endif

int main (int argc, char **argv)


{
  med_idt fid;
  char maa[MED_NAME_SIZE+1] = "maa1";
  med_int mdim = 3;
  med_int n=2;
  /* connectivite nodale */
  med_int indexf[3] = {1,5,9};
  med_int nf = 3;
  med_int indexn[9] = {1,4,7,10,13,16,19,22,25};
  med_int nn = 9;
  med_int conn[24] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
                      20,21,22,23,24};
  /* connectivite descendante */
  med_int indexf2[3] = {1,5,9};
  med_int nf2 = 3;
  med_int conn2[8] = {1,2,3,4,5,6,7,8};
  med_int indexn2[8] = {MED_TRIA3,MED_TRIA3,MED_TRIA3,MED_TRIA3,
                        MED_TRIA3,MED_TRIA3,MED_TRIA3,MED_TRIA3};
  med_int nn2=8;
  /*                             12345678901234561234567890123456*/
  char nom[MED_SNAME_SIZE*2+1]="polyedre1       polyedre2       ";
  med_int num[2] = {1,2};
  med_int fam[2] = {0,-1};
  char nomcoo[3*MED_SNAME_SIZE+1] = "x               y               z               ";
  char unicoo[3*MED_SNAME_SIZE+1] = "cm              cm              cm              ";

  /* Creation du fichier test25.med */
  if ((fid = MEDfileOpen("test25.med",MODE_ACCES)) < 0) {
    MESSAGE("Erreur a la creation du fichier test25.med");
    return -1;
  }
  printf("Creation du fichier test25.med \n");

  /* Creation du maillage */
 if (MEDmeshCr( fid, maa, mdim, mdim, MED_UNSTRUCTURED_MESH,
                 "un maillage pour test25","s", MED_SORT_DTIT,
                 MED_CARTESIAN, nomcoo, unicoo) < 0) {
    MESSAGE("Erreur a la creation du maillage");
    return -1;
   }
  printf("Creation du maillage \n");

  /* Ecriture de la connectivite des mailles polyedres en mode nodal */
  if (MEDmeshPolyhedronWr(fid,maa,MED_NO_DT,MED_NO_IT,MED_UNDEF_DT,MED_CELL,MED_NODAL,
                          nf,indexf,nn,indexn,conn) < 0) {
    MESSAGE("Erreur a l'ecriture de la connectivite des mailles MED_POLYGONE");
    return -1;
  }
  printf("Ecriture des connectivites de mailles de type MED_POLYEDRE en mode nodal \n");

  /* Ecriture des connectivites des mailles polyedres en mode descendant */
  if (MEDmeshPolyhedronWr(fid,maa,MED_NO_DT,MED_NO_IT,MED_UNDEF_DT,MED_CELL,MED_DESCENDING,
                          nf2,indexf2,nn2,indexn2,conn2) < 0) {
    MESSAGE("Erreur a l'ecriture des connectivites des mailles MED_POLYEDRE en mode descendant");
    return -1;
  }
  printf("Ecriture des connectivites de mailles de type MED_POLYEDRE en mode descendant \n"); 


  /* Ecriture des noms des polyedres */
  /* ecriture (optionnelle) des noms des polyedres */
  if (MEDmeshEntityNameWr(fid,maa,MED_NO_DT,MED_NO_IT,
                          MED_CELL,MED_POLYHEDRON,n,nom) < 0) {
    MESSAGE("Erreur a l'ecriture des noms des polyedres");
    return -1;
  }
  printf("Ecriture des noms des polyedres \n");

  /* ecriture (optionnelle) des numeros des polyedres */
  if (MEDmeshEntityNumberWr(fid,maa,MED_NO_DT,MED_NO_IT,
                            MED_CELL,MED_POLYHEDRON,n,num) < 0) {
    MESSAGE("Erreur a l'ecriture des numeros des polyedres");
    return -1;
  }
  printf("Ecriture des numeros des polyedres \n");

  /* ecriture des numeros des familles des polyedres */
  if (MEDmeshEntityFamilyNumberWr(fid,maa,MED_NO_DT,MED_NO_IT,
                                  MED_CELL,MED_POLYHEDRON,n,fam) < 0) {
    MESSAGE("Erreur a l'ecriture des numeros de familles des polyedres");
    return -1;
  }
  printf("Ecriture des numeros des familles des polyedres \n");

  /* Fermeture du fichier */
  if (MEDfileClose(fid) < 0) {
    MESSAGE("Erreur a la fermeture du fichier");
    return -1;
  }
  printf("Fermeture du fichier test25.med \n");

  return 0; 
}

La lecture de la connectivité des polyèdres d'un maillage demande une approche spécifique. Il est d'abord nécessaire d'appeler plusieurs fois la routine MEDmeshnEntity / mmhnme afin de récupérer la taille des tableaux d'indexation. Enfin la routine MEDmeshPolyhedronRd / mmhphr va lire les tableaux d'indexation et de connectivité, comme l'illustre le cas d'utilisation suivant.

/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */


/******************************************************************************
 * - Nom du fichier : test26.c
 *
 * - Description : lecture de mailles de type MED_POLYEDRE
 *                 dans le maillage MED du fichier test25.med
 *
 *****************************************************************************/

#include <med.h>
#define MESGERR 1
#include "med_utils.h"
#include <string.h>

#ifdef DEF_LECT_ECR
#define MODE_ACCES MED_ACC_RDWR
#elif DEF_LECT_AJOUT
#define MODE_ACCES MED_ACC_RDEXT
#else
#define MODE_ACCES MED_ACC_CREAT
#endif

#define MAXDIM 3

int main (int argc, char **argv)


{
  med_err ret = 0;
  med_idt fid;
  char maa[MED_NAME_SIZE+1];
  med_int nmaa,i,j,mdim;
  char desc[MED_COMMENT_SIZE+1];
  med_int taille,nindf,nindn,npoly;
  med_int taille2,nindf2,nindn2;
  med_int *conn, *conn2, *indexn, *indexn2, *num, *fam;
  med_int *indexf, *indexf2;
  char *nom;
  char tmp[MED_SNAME_SIZE+1];
  int ind1, ind2,k,nfaces,nnoeuds,l;
  char dtunit[MED_SNAME_SIZE+1]="";
  char nomcoo[MAXDIM*MED_SNAME_SIZE+1];
  char unicoo[MAXDIM*MED_SNAME_SIZE+1];
  med_mesh_type type;
  med_sorting_type sort;
  med_axis_type rep;
  med_int nstep=0,sdim=0;
  med_int inoele=0,inuele=0,ifaele=0;
  med_bool chgt=MED_FALSE,trsf=MED_FALSE;;

  /* Ouverture du fichier test25.med en lecture seule */
  fid = MEDfileOpen("test25.med",MED_ACC_RDONLY);
  if (fid < 0) {
    MESSAGE("Erreur a l'ouverture du fichier test25.med");
    return -1;
  }
  printf("Ouverture du fichier test25.med \n");

  /* Lecture du nombre de maillages */
  nmaa = MEDnMesh(fid);
  if (nmaa < 0) {
    MESSAGE("Erreur a lecture du nombre de maillage");
    return -1;
  }
  printf("Nombre de maillages = "IFORMAT"\n",nmaa);

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

    /* Lecture des infos sur le maillage */
    if ( MEDmeshInfo( fid, i+1,  maa, &sdim, &mdim, &type, desc, dtunit, &sort,
                      &nstep,  &rep, nomcoo, unicoo) < 0 ) {
      MESSAGE("Erreur a lecture des infos sur le maillage");
      return -1;
    } else {
      printf("maillage "IFORMAT" de nom [%s] et de dimension : "IFORMAT" , et de type %d\n",i+1,maa,mdim,type);
      printf("\t -Dimension de l'espace : "IFORMAT"\n",sdim);
      printf("\t -Description du maillage : |%s|\n",desc);
      printf("\t -Noms des axes : |%s|\n",nomcoo);
      printf("\t -Unités des axes : |%s|\n",unicoo);
      printf("\t -Type de repère : %d\n",rep);
      printf("\t -Nombre d'étapes de calcul : "IFORMAT"\n",nstep);
      printf("\t -Unité des dates : |%s|\n",dtunit);
    }

    printf("maillage "IFORMAT" de nom [%s] et de dimension : "IFORMAT" \n",i+1,maa,mdim);

    /* Taille du tableau d'index des faces constituant chacun des polyedres */
    if ((nindf = MEDmeshnEntity(fid,maa,MED_NO_DT,MED_NO_IT,
                                MED_CELL,MED_POLYHEDRON,MED_INDEX_FACE,MED_NODAL,
                                &chgt,&trsf)) < 0) {
      MESSAGE("Erreur a lecture du nombre de maille MED_POLYEDRE en mode nodal");
      return -1;
    }
    npoly = nindf-1;
    printf("Nombre de mailles polyedres : "IFORMAT" \n",npoly);

    /* Taille du tableau d'index des noeuds constituant chacune des faces en mode nodal */
    if ((nindn = MEDmeshnEntity(fid,maa,MED_NO_DT,MED_NO_IT,
                                MED_CELL,MED_POLYHEDRON,MED_INDEX_NODE,MED_NODAL,
                                &chgt,&trsf)) < 0) {
      MESSAGE("Erreur a lecture des infos sur les polyedres");
      return -1;
    }
    printf("Taille a allouer pour le tableau des faces (d'indexation des noeuds),(nodal) : "IFORMAT" \n",nindn);

    /* Taille du tableau d'index des type constituant chacune des faces en mode descendant */
    if ((nindn2 = MEDmeshnEntity(fid,maa,MED_NO_DT,MED_NO_IT,
                                 MED_CELL,MED_POLYHEDRON,MED_INDEX_NODE,MED_DESCENDING,
                                 &chgt,&trsf)) < 0) {
      MESSAGE("Erreur a lecture des infos sur les polyedres");
      return -1;
    }
    printf("Taille a allouer pour le tableau des types de faces (descendant) : "IFORMAT" \n",nindn2);

    /* Taille du tableau de connectivité en mode MED_NODAL */
    if ((taille = MEDmeshnEntity(fid,maa,MED_NO_DT,MED_NO_IT,
                                 MED_CELL,MED_POLYHEDRON,MED_CONNECTIVITY,MED_NODAL,
                                 &chgt,&trsf)) < 0) {
      MESSAGE("Erreur a la lecture des infos sur les polyedres");
      return -1;
    }
    printf("Taille a allouer pour le tableau des noeuds des polyedres (connectivite),(nodal) : "IFORMAT" \n",taille);

    /* Taille du tableau de connectivité en mode MED_DESCENDING */
    if ((taille2 = MEDmeshnEntity(fid,maa,MED_NO_DT,MED_NO_IT,
                                  MED_CELL,MED_POLYHEDRON,MED_CONNECTIVITY,MED_DESCENDING,
                                  &chgt,&trsf)) < 0) {
      MESSAGE("Erreur a la lecture des infos sur les polyedres");
      return -1;
    }
    printf("Taille a allouer pour le tableau des noeuds des polyedres (connectivite),(descendant) : "IFORMAT" \n",taille2);


    /* Allocation memoire :
     *  - tableau indexf et indexf2 : nindf
     *  - tableau indexn et indexn2 : nindn et nindn2
     *  - tableau des connectivites : consize
     *  - tableaux numeros et numeros de familles : npoly
     *  - tableau des noms : MED_SNAME_SIZE*npoly + 1
     */
    indexf   = (med_int *) malloc(sizeof(med_int)*nindf);
    indexf2  = (med_int *) malloc(sizeof(med_int)*nindf);
    indexn   = (med_int *) malloc(sizeof(med_int)*nindn);
    indexn2  = (med_int *) malloc(sizeof(med_int)*nindn2);
    conn    = (med_int *) malloc(sizeof(med_int)*taille);
    conn2   = (med_int *) malloc(sizeof(med_int)*taille2);
    num     = (med_int *) malloc(sizeof(med_int)*npoly);
    fam     = (med_int *) calloc(sizeof(med_int),npoly);
    nom     = (char *)    malloc(sizeof(char)*MED_SNAME_SIZE*npoly+1);

    /* Lecture de la connectivite des mailles polyedres en mode nodal */
    if (MEDmeshPolyhedronRd(fid,maa,MED_NO_DT,MED_NO_IT,MED_CELL,MED_NODAL,
                            indexf,indexn,conn) < 0) {
      MESSAGE("Erreur a lecture de la connectivite nodale des polyedres");
      return -1;
    }

    printf("Lecture de la connectivite des mailles MED_POLYEDRE en mode nodal \n");

    /* Lecture de la connectivite des mailles polyedres en mode descendant */
    if (MEDmeshPolyhedronRd(fid,maa,MED_NO_DT,MED_NO_IT,MED_CELL,MED_DESCENDING,
                            indexf2,indexn2,conn2) < 0) {
      MESSAGE("Erreur a lecture de la connectivite descendante des polyedres");
      return -1;
    }
    printf("Lecture de la connectivite des mailles MED_POLYEDRE en mode descendant \n");

    /* Lecture noms */
    if ( (inoele = MEDmeshnEntity(fid,maa,MED_NO_DT,MED_NO_IT,
                                 MED_CELL,MED_POLYHEDRON,MED_NAME,MED_DESCENDING,
                                 &chgt,&trsf)) < 0) {
      MESSAGE("Erreur de detection de la présence de noms optionnels des polyedres");
      return -1;
    }
    if ( inoele ) {
      if (MEDmeshEntityNameRd(fid,maa,MED_NO_DT,MED_NO_IT,
                              MED_CELL,MED_POLYHEDRON,nom) < 0) {
        MESSAGE("Erreur à la lecture des noms optionnels des polyedres");
      } else {
        printf("Lecture des noms des mailles MED_POLYEDRE \n");
      }
    }

    /* Lecture des numeros */
    if ( (inuele = MEDmeshnEntity(fid,maa,MED_NO_DT,MED_NO_IT,
                                  MED_CELL,MED_POLYHEDRON,MED_NUMBER,MED_DESCENDING,
                                  &chgt,&trsf)) < 0) {
      MESSAGE("Erreur de detection de la présence de noms optionnels des polyedres");
      return -1;
    }
    if ( inuele) {
      if (MEDmeshEntityNumberRd(fid,maa,MED_NO_DT,MED_NO_IT,
                                MED_CELL,MED_POLYHEDRON,num) < 0) {
        MESSAGE("Erreur à la lecture des numeros optionnels des polyedres");
      } else {
        printf("Lecture des numeros des mailles MED_POLYEDRE \n");
      }
    }

    /* Lecture des numeros de familles */
    if ( (ifaele = MEDmeshnEntity(fid,maa,MED_NO_DT,MED_NO_IT,
                                  MED_CELL,MED_POLYHEDRON,MED_FAMILY_NUMBER,MED_DESCENDING,
                                  &chgt,&trsf)) < 0) {
      MESSAGE("Erreur de detection de la présence des numéros de familles des polyedres");
      return -1;
    }
    if ( ifaele )
      if (MEDmeshEntityFamilyNumberRd(fid,maa,MED_NO_DT,MED_NO_IT,
                                      MED_CELL,MED_POLYHEDRON,fam) < 0) {
        MESSAGE("Erreur a lecture des numeros de famille des polyedres");
        /*TODO : Considérer famille 0 */
        return -1;
      }
    printf("Lecture des numeros de familles des mailles MED_POLYEDRE \n");

    printf("Affichage des resultats \n");
    for (j=0;j<npoly;j++) {

      printf(">> Maille MED_POLYEDRE "IFORMAT" : \n",j+1);
      printf("---- Connectivite nodale      ----- : \n");
      nfaces  = *(indexf+j+1) - *(indexf+j);
      ISCRUTE_int(nfaces);
      /* ind1 = indice dans "faces" pour acceder aux numeros des faces */
      ind1 = *(indexf+j) - 1;
      for (k=0;k<nfaces;k++) {
        /* ind2 = indice dans "conn" pour acceder au premier noeud de la face */
        ind2 = *(indexn+ind1+k) - 1;
        nnoeuds = *(indexn+ind1+k+1) - *(indexn+ind1+k);
        printf("   - Face %d : [ ", k+1);
        for (l=0;l<nnoeuds;l++)
          printf(" "IFORMAT" ",*(conn+ind2+l));
        printf(" ] \n");
      }
      printf("---- Connectivite descendante ----- : \n");
      nfaces  = *(indexf2+j+1) - *(indexf2+j);
      /* ind1 = indice dans "conn2" pour acceder aux numeros des faces */
      ind1 = *(indexf2+j) - 1;
      for (k=0;k<nfaces;k++)
        printf("   - Face %d de numero : "IFORMAT" et de type "IFORMAT" \n", k+1,*(conn2+ind1+k),*(indexn2+ind1+k));
      strncpy(tmp,nom+j*MED_SNAME_SIZE,MED_SNAME_SIZE);
      tmp[MED_SNAME_SIZE] = '\0';
      if (inoele) printf("---- Nom                      ----- : %s \n",tmp);
      if (inuele) printf("---- Numero                   ----- : "IFORMAT" \n",*(num+j));
      printf("---- Numero de famille        ----- : "IFORMAT" \n",*(fam+j));
    }


    /* liberation de la memoire */
    free(indexf);
    free(indexf2);
    free(indexn);
    free(indexn2);
    free(conn);
    free(conn2);
    free(num);
    free(fam);
    free(nom);
  }

  /* Fermeture du fichier */
  if (MEDfileClose(fid) < 0) {
    MESSAGE("Erreur a fermeture du fichier");
    return -1;
  }
    printf("Fermeture du fichier \n");

    return ret;
}

Créer et lire un maillage avec gestion des profils sur les entités

Un profil sur les entités d'un maillage permet l'écriture ou la lecture sur un sous-ensemble de ces entités. Un profil est un objet stocké dans un fichier MED. Un profil est un tableau de numéros d'entités (numérotation MED relative à un type géométrique d'élément commençant à 1) associés aux valeurs à traiter. La définition d'un profil se fait selon les conventions suivantes : les numéros d'entité utilisés pour définir un profil sont ceux de la numérotation implicite (ordre d'apparition des entités par ordre croissant). Un profil est une liste compacte : on ne met que les numéros représentatifs. Exemple : sur un maillage de 30 noeuds, si on a un champ portant sur les noeuds de numéros de référence 4, 5 et 12, le profil correspondant sera la liste (4,5,12).

La routine MEDprofileWr / mpfprw permet d'écrire un profil dans un fichier MED. Un profil est identifié par son nom (chaîne de taille MED_NAME_SIZE caractères).

A la lecture, la routine MEDnProfile / mpfnpf va lire le nombre de profil dans un fichier. Il s'agit ensuite d'itérer sur chaque profil afin de récupérer pour chacun d'eux : le nom et la taille du tableau du profil avec la routine MEDprofileInfo / mpfpfi, le tableau des numéros d'entités avec MEDprofileRd / mpfprr.

Lorsqu'on connaît le nom du profil, la routine permet MEDprofileSizeByName / mpfpsn de lire la taille du tableau.

Au niveau de l'API sur les maillages, l'utilisation des profils est possible en écriture ou en lecture des coordonées des noeuds et de la connectivité des éléments d'un maillage non structuré avec les routines : MEDmeshNodeCoordinateWithProfileWr / mmhcow pour l'écriture des coordonnées, MEDmeshNodeCoordinateWithProfileRd / mmhcor pour la lecture des coordonnées, MEDmeshElementConnectivityWithProfileWr / mmhypw pour l'écriture des connectivités, MEDmeshElementConnectivityWithProfileRd / mmhypr pour la lecture des connectivités. A noter également la routine MEDmeshnEntityWithProfile / mmhnep qui peut récupérer le nombre d'entité à lire selon un profil donné.

Pour toutes ces routines, il est possible de spécifier le mode de stockage des tableaux de coordonnées ou de connectivité en mémoire. Deux modes sont possibles : le mode MED_GLOBAL_PFLMODE indique que le stockage utilisé contient en mémoire toutes les valeurs relatives à toutes les entités d'un même type ; le mode MED_COMPACT_PFLMODE indique que le stockage utilisé est compact et ne contient en mémoire que le sous-ensemble de valeurs relatives au profil.

Créer et lire un maillage évolutif

Dans MED, un maillage peut évoluer par étape, chaque étape étant estampillée par un couple <pas de temps, numéro d'ordre> à l'instar des étapes de calcul d'un champ de résultat.

Une évolution peut porter un maillage déformable à topologie constante (les coordonnées des noeuds ou d'un sous-ensemble des noeuds sont modifiées à chaque étape), un maillage à déformation solide (selon une matrice de transformation pour chaque étape applicable aux coordonnées des noeuds), un maillage redéfinissable (les connectivités des mailles changent au cours des étapes).

A la création d'une étape de calcul, les informations de l'étape précédente inchangées sont automatiquement reportées : coordonnées, connectivités, numéros optionnels, noms optionnels, numéros de famille. Il est donc possible de créer une étape d'évolution sans avoir à y reporter toutes ces données. L'utilisateur a la responsabilité de maintenir la cohérence des informations covariantes au cours des différentes étapes.

A noter qu'un champ de résultat repose désormais sur une étape d'évolution existante d'un maillage (par défaut l'étape initiale <MED_NO_DT, MED_NO_IT>). Il est nécessaire de stocker le maillage initial <MED_NO_DT, MED_NO_IT> avant toute évolution.

Au cours des évolutions d'un maillage, les types géométriques d'éléments doivent rester identiques. Si de nouveaux types géométriques apparaissent, il faut créer un nouveau maillage.

Pour ce qui concerne l'écriture des maillages déformables à topologie constante, il faut utiliser la routine MEDmeshNodeCoordinateWithProfileWr / mmhcow en passant en paramètre le pas de temps et ou le numéro d'ordre correspondant à l'étape, le profil sélectionnant les noeuds dont les coordonnées sont modifiées, le tableau des nouvelles coordonnées.

Le cas d'utilisation suivant après création du maillage initial, créée 2 évolutions successives de sous-ensembles des coordonnées des noeuds du maillage.

/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 *  How to create an unstructured mesh 
 *
 *  Use case 6 : a 2D unstructured mesh with the following features 
 *  computin steps, profiles and nodes coordinates evolution.
 */

#include <med.h>
#define MESGERR 1
#include <med_utils.h>

#include <string.h>

int main (int argc, char **argv) {
  med_idt fid;
  const char meshname[MED_NAME_SIZE+1] = "2D unstructured mesh";
  const med_int spacedim = 2;
  const med_int meshdim = 2;
  const char axisname[2*MED_SNAME_SIZE+1] = "x               y               ";
  const char unitname[2*MED_SNAME_SIZE+1] = "cm              cm              ";
  const med_float initial_coordinates[30] = { 2.,1.,  7.,1.,  12.,1.,  17.,1.,  22.,1.,
                                              2.,6.,  7.,6.,  12.,6.,  17.,6.,  22.,6.,
                                              2.,11., 7.,11., 12.,11., 17.,11., 22.,11.};
  const med_int nnodes = 15;
  const med_int triaconnectivity[24] = { 1,7,6,   2,7,1,  3,7,2,   8,7,3,   
                                         13,7,8, 12,7,13, 11,7,12, 6,7,11 };
  const med_int ntria3 = 8;
  const med_int quadconnectivity[16] = {3,4,9,8,    4,5,10,9, 
                                        15,14,9,10, 13,8,9,14};
  const med_int nquad4 = 4;
  /* new coordinates (step 1) for nodes 13, 14 and 15 */
  const med_float new_coordinates_step1 [6] = { 12.,15., 17.,15., 22.,15.};
  const char profile1name[MED_NAME_SIZE+1] = "UPPER_QUAD4_PROFILE";
  const med_int profile1[3] = {13, 14, 15}; 
  const med_int profile1size = 3;
  /* new coordinates (step 2) for nodes 8, 9 and 10 */
  const med_float new_coordinates_step2 [6] = { 12.,10., 17.,10., 22.,10.};
  const char profile2name[MED_NAME_SIZE+1] = "MIDDLE_QUAD4_PROFILE";
  const med_int profile2[3] = {8, 9, 10}; 
  const med_int profile2size = 3;
  int ret=-1;
  
  
  /* open MED file */
  fid = MEDfileOpen("UsesCase_MEDmesh_6.med",MED_ACC_CREAT);
  if (fid < 0) {
    MESSAGE("ERROR : file creation ...");
    goto ERROR;
  }

  /* write a comment in the file */
  if (MEDfileCommentWr(fid,"A 2D unstructured mesh : 15 nodes, 12 cells") < 0) {
    MESSAGE("ERROR : write file description ...");
    goto ERROR;
  }

  /* create the profiles in the file */
  if (MEDprofileWr(fid, profile1name, profile1size, profile1 ) < 0) {
    MESSAGE("ERROR : create profile ...");
    goto ERROR; 
  }

  if (MEDprofileWr(fid, profile2name, profile2size, profile2 ) < 0) {
    MESSAGE("ERROR : create profile ...");
    goto ERROR; 
  }
  
  /* mesh creation : a 2D unstructured mesh */
  if (MEDmeshCr(fid, meshname, spacedim, meshdim, MED_UNSTRUCTURED_MESH, 
                "A 2D unstructured mesh","",MED_SORT_DTIT,MED_CARTESIAN, axisname, unitname) < 0) {
    MESSAGE("ERROR : mesh creation ...");
    goto ERROR;
  }

  /* initial nodes coordinates in a cartesian axis in full interlace mode 
     (X1,Y1, X2,Y2, X3,Y3, ...) 
  */
  if (MEDmeshNodeCoordinateWithProfileWr(fid, meshname, MED_NO_DT, MED_NO_IT, 0.0,
                                         MED_COMPACT_PFLMODE, MED_NO_PROFILE,
                                         MED_FULL_INTERLACE, MED_ALL_CONSTITUENT,
                                         nnodes, initial_coordinates) < 0) {
    MESSAGE("ERROR : nodes coordinates ...");
    goto ERROR;
  }

  /* cells connectiviy is defined in nodal mode */
  if (MEDmeshElementConnectivityWithProfileWr(fid, meshname, MED_NO_DT, MED_NO_IT, 0.0,
                                              MED_CELL, MED_TRIA3, MED_NODAL, 
                                              MED_COMPACT_PFLMODE, MED_NO_PROFILE,
                                              MED_FULL_INTERLACE, MED_ALL_CONSTITUENT, 
                                              ntria3, triaconnectivity) < 0) {
    MESSAGE("ERROR : triangular cells connectivity ...");
    goto ERROR;
  }

  if (MEDmeshElementConnectivityWithProfileWr(fid, meshname, MED_NO_DT, MED_NO_IT, 0.0,
                                              MED_CELL, MED_QUAD4, MED_NODAL, 
                                              MED_COMPACT_PFLMODE, MED_NO_PROFILE,
                                              MED_FULL_INTERLACE, MED_ALL_CONSTITUENT,  
                                              nquad4, quadconnectivity) < 0) {
    MESSAGE("ERROR : quadrangular cells connectivity ..."); 
    goto ERROR;
  }

  /* 
   * Mesh deformation (nodes coordinates) in 2 steps 
   * The nodes modified are identified by a profile 
   */ 
  /* STEP 1 : dt1 = 5.5, it = 1*/
  if (MEDmeshNodeCoordinateWithProfileWr(fid, meshname, 1, 1, 5.5,
                                         MED_COMPACT_PFLMODE, profile1name,
                                         MED_FULL_INTERLACE, MED_ALL_CONSTITUENT,
                                         nnodes, new_coordinates_step1 ) < 0) {
    MESSAGE("ERROR : nodes coordinates ...");
    goto ERROR;
  }
  /* STEP 2 : dt2 = 8.9, it = 1*/
  if (MEDmeshNodeCoordinateWithProfileWr(fid, meshname, 2, 1, 8.9,
                                         MED_COMPACT_PFLMODE, profile2name,
                                         MED_FULL_INTERLACE, MED_ALL_CONSTITUENT,
                                         nnodes, new_coordinates_step2 ) < 0) {
    MESSAGE("ERROR : nodes coordinates ...");
    goto ERROR;
  }

  /* create family 0 : by default, all mesh entities family number is 0 */
  if (MEDfamilyCr(fid, meshname,MED_NO_NAME, 0, 0, MED_NO_GROUP) < 0) {
    MESSAGE("ERROR : quadrangular cells connectivity ...");
    goto ERROR;
  }
  
  ret=0;
 ERROR:
  
  /* close MED file */
  if (MEDfileClose(fid)  < 0) {
    MESSAGE("ERROR : close file ...");
    ret=-1;
  }

  return ret;
}

A la lecture des maillages déformables à topologie constante, une fois la lecture du maillage initiale effectuée, il faut itérer sur les différentes étapes d'évolution présentes dans le maillage (le nombre d'étape est lue par les routines MEDmeshInfoByName / mmhmin ou MEDmeshInfo / mmhmii) et à chaque étape : récupérer les valeurs du pas de temps et du numéro d'itération avec la routine MEDmeshComputationStepInfo / mmhcsi ; déterminer la nature du changement parmi les cas possibles pré-cités avec la routine MEDmeshnEntityWithProfile / mmhnep et également récupérer le nombre de noeuds à lire selon le mode de stockage mémoire passé en paramètre ; lire les nouvelles coordonnées des noeuds avec la routine MEDmeshNodeCoordinateWithProfileRd / mmhcor.

C'est ce que fait le cas d'utilisation suivant.

/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 *  Use case 7 : read a 2D unstructured mesh with nodes coordinates modifications
 */

#include <med.h>
#define MESGERR 1
#include <med_utils.h>

#include <string.h>

int main (int argc, char **argv) {
  med_idt fid;
  const char meshname[MED_NAME_SIZE+1] = "2D unstructured mesh";
  char meshdescription[MED_COMMENT_SIZE+1]="";
  med_int meshdim;
  med_int spacedim;
  med_sorting_type sortingtype;
  med_int nstep;
  med_mesh_type meshtype;
  med_axis_type axistype;
  char axisname[2*MED_SNAME_SIZE+1]="";
  char unitname[2*MED_SNAME_SIZE+1]="";
  char dtunit[MED_SNAME_SIZE+1]="";
  med_float *coordinates = NULL;
  med_int nnodes = 0;
  med_int *triaconnectivity = NULL;
  med_int ntria3 = 0;
  med_int *quadconnectivity = NULL;
  med_int nquad4 = 0;
  med_bool coordinatechangement;
  med_bool geotransformation;
  int i, it;
  med_int profilesize;
  char profilename[MED_NAME_SIZE+1]="";
  med_int numdt, numit;
  med_float dt;
  int ret=-1;

  /* open MED file with READ ONLY access mode */
  fid = MEDfileOpen("UsesCase_MEDmesh_6.med",MED_ACC_RDONLY);
  if (fid < 0) {
    MESSAGE("ERROR : open file in READ ONLY ACCESS mode ...");
    goto ERROR;
  }

  /* 
   * ... we know that the MED file has only one mesh, 
   * a real code working would check ... 
   */

  /* read mesh informations : mesh dimension, space dimension ... */
  if (MEDmeshInfoByName(fid, meshname, &spacedim, &meshdim, &meshtype, meshdescription, 
                        dtunit, &sortingtype, &nstep, &axistype, axisname, unitname) < 0) {
    MESSAGE("ERROR : mesh info ...");
    goto ERROR;
  }

  /* read how many nodes in the mesh */
  if ((nnodes = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_NODE,  MED_NO_GEOTYPE,
                               MED_COORDINATE, MED_NO_CMODE,&coordinatechangement,
                               &geotransformation)) < 0) {
    MESSAGE("ERROR : number of nodes ...");
    goto ERROR;
  }
  
  /* 
   * ... we know that we only have MED_TRIA3 and MED_QUAD4 in the mesh, 
   * a real code working would check all MED geometry cell types ... 
   */

  /* read how many triangular cells in the mesh */
  if ((ntria3 = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL,MED_TRIA3,
                               MED_CONNECTIVITY, MED_NODAL,&coordinatechangement,
                               &geotransformation)) < 0) {
    MESSAGE("ERROR : number of MED_TRIA3 ...");
    goto ERROR;
  }

  /* read how many quadrangular cells in the mesh */
  if ((nquad4 = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL,MED_QUAD4,
                               MED_CONNECTIVITY, MED_NODAL, &coordinatechangement,
                               &geotransformation)) < 0) {
    MESSAGE("ERROR : number of MED_QUAD4 ...");
    goto ERROR;
  }

  /* read mesh nodes coordinates in the initial mesh */
  if ((coordinates = (med_float*) malloc(sizeof(med_float)*nnodes*spacedim)) == NULL) {
    MESSAGE("ERROR : memory allocation ...");
    goto ERROR;
  }

  if (MEDmeshNodeCoordinateRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_FULL_INTERLACE,
                              coordinates) < 0) {
    MESSAGE("ERROR : nodes coordinates ...");
    free(coordinates);
    goto ERROR;
  }

  /* read cells connectivity in the initial mesh */
  if ((triaconnectivity = (med_int *) malloc(sizeof(med_int)*ntria3*3)) == NULL) {
    MESSAGE("ERROR : memory allocation ...");
    goto ERROR;
  }
  if (MEDmeshElementConnectivityRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL,
                                   MED_TRIA3, MED_NODAL, MED_FULL_INTERLACE, triaconnectivity) < 0) {
    MESSAGE("ERROR : MED_TRIA3 connectivity ...");
    free(triaconnectivity);
    goto ERROR;
  }
  free(triaconnectivity);

  if ((quadconnectivity = (med_int *) malloc(sizeof(med_int)*nquad4*4)) == NULL) {
    MESSAGE("ERROR : memory allocation ...");
    goto ERROR;
  }
  if (MEDmeshElementConnectivityRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL,
                                   MED_QUAD4, MED_NODAL, MED_FULL_INTERLACE, quadconnectivity) < 0) {
    MESSAGE("ERROR : MED_QUAD4 connectivity ...");
    free(quadconnectivity);
    goto ERROR;
  }
  free(quadconnectivity);

  /* 
   * ... we know that the family number of nodes and elements is 0, a real working would check ...
   */

  /* read nodes coordinates changements step by step */
  for (it=1;it<nstep;it++) {

    if (MEDmeshComputationStepInfo(fid, meshname, it+1, 
                                   &numdt, &numit, &dt) < 0) {
      MESSAGE("ERROR : Computing step info ...");
      SSCRUTE(meshname);
      goto ERROR;
    }
  
    /* test changement : for nodes coordinates */
    if ((nnodes = MEDmeshnEntityWithProfile(fid, meshname, numdt, numit, 
                                            MED_NODE,  MED_NO_GEOTYPE,
                                            MED_COORDINATE, MED_NO_CMODE,
                                            MED_GLOBAL_PFLMODE, profilename, &profilesize,
                                            &coordinatechangement, &geotransformation)) < 0) {
      MESSAGE("ERROR : number of nodes ...");
      goto ERROR;
    }

    /* if coordinates have changed, then read the new coordinates */
    if (coordinatechangement) {
      if (MEDmeshNodeCoordinateWithProfileRd(fid, meshname, numdt, numit, 
                                             MED_GLOBAL_PFLMODE,profilename,
                                             MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,
                                             coordinates) < 0) {
        MESSAGE("ERROR : nodes coordinates ...");
        free(coordinates);
        goto ERROR;
      }
    }
      
  }

  free(coordinates);
  
  ret=0;
 ERROR:

  /* close MED file */
  if (MEDfileClose(fid) < 0) {
    MESSAGE("ERROR : close file");             
    ret=-1; 
  } 


  return ret;
}

Le cas d'utilisation suivant propose une approche plus générique dans la lecture des maillages déformables à topologie constante.

/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 *  Use case 8 : read a 2D unstructured mesh with coordinates nodes 
 *  modifications (generic approach)
 */

#include <med.h>
#define MESGERR 1
#include <med_utils.h>

#include <string.h>

int main (int argc, char **argv) {
  med_idt fid;
  med_int nmesh;
  char meshname[MED_NAME_SIZE+1]="";
  char meshdescription[MED_COMMENT_SIZE+1]="";
  med_int meshdim;
  med_int spacedim;
  med_sorting_type sortingtype;
  med_int nstep;
  med_mesh_type meshtype;
  med_axis_type axistype;
  char *axisname;
  char *unitname;
  char dtunit[MED_SNAME_SIZE+1]="";
  med_float *coordinates = NULL;
  med_int ngeo = 0;
  med_int nnodes = 0;
  med_int *connectivity = NULL;
  med_bool coordinatechangement;
  med_bool geotransformation;
  int i, it, j;
  med_int profilesize;
  char profilename[MED_NAME_SIZE+1]="";
  med_int numdt, numit;
  med_float dt;
  med_geometry_type geotype;
  med_geometry_type *geotypes = MED_GET_CELL_GEOMETRY_TYPE;
  int ret=-1;

  /* open MED file with READ ONLY access mode */
  fid = MEDfileOpen("UsesCase_MEDmesh_6.med",MED_ACC_RDONLY);
  if (fid < 0) {
    MESSAGE("ERROR : open file in READ ONLY ACCESS mode ...");
    goto ERROR;
  }


  /* read how many mesh in the file */
  if ((nmesh = MEDnMesh(fid)) < 0) {
    MESSAGE("ERROR : read how many mesh ...");
    goto ERROR;
  }

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

    /* read computation space dimension */
    if ((spacedim = MEDmeshnAxis(fid, i+1)) < 0) {
      MESSAGE("ERROR : read computation space dimension ...");
      goto ERROR;
    }
    
    /* memory allocation */
    if ((axisname  = (char*) malloc(MED_SNAME_SIZE*spacedim+1)) == NULL) {
      MESSAGE("ERROR : memory allocation ...");
      goto ERROR;
    }
    if ((unitname  = (char*) malloc(MED_SNAME_SIZE*spacedim+1)) == NULL) {
      MESSAGE("ERROR : memory allocation ...");
      goto ERROR;
    }

    /* read mesh informations : meshname, mesh dimension, mesh type ... */
    if (MEDmeshInfo(fid, i+1, meshname, &spacedim, &meshdim, &meshtype, meshdescription, 
                    dtunit, &sortingtype, &nstep,  
                    &axistype, axisname, unitname) < 0) {
      MESSAGE("ERROR : mesh info ...")
        free(axisname);
      free(unitname);
      goto ERROR;
    }
    free(axisname);
    free(unitname);


    /* read how many nodes in the mesh */
    if ((nnodes = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_NODE, MED_NONE,
                                 MED_COORDINATE, MED_NO_CMODE,&coordinatechangement,
                                 &geotransformation)) < 0) {
      MESSAGE("ERROR : number of nodes ...");
      goto ERROR;
    }
  
    /* read mesh nodes coordinates */
    if ((coordinates = (med_float*) malloc(sizeof(med_float)*nnodes*spacedim)) == NULL) {
      MESSAGE("ERROR : memory allocation ...");
      goto ERROR;
    }
    
    if (MEDmeshNodeCoordinateRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_FULL_INTERLACE,
                                coordinates) < 0) {
      MESSAGE("ERROR : nodes coordinates ...");
      free(coordinates);
      goto ERROR;
    }
    

    /* read all MED geometry cell types */
    for (it=1; it<=MED_N_CELL_FIXED_GEO; it++) {   

      geotype = geotypes[it];   

      if ((ngeo = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL,geotype,
                                 MED_CONNECTIVITY, MED_NODAL, &coordinatechangement,
                                 &geotransformation)) < 0) {
        MESSAGE("ERROR : number of cell ...");
        ISCRUTE(geotype);
        goto ERROR;
      }
    
      if (ngeo) {
        /* read cells connectivity in the mesh */
        if ((connectivity = (med_int *) malloc(sizeof(med_int)*ngeo*(geotype%100))) == NULL) {
          MESSAGE("ERROR : memory allocation ...");
          goto ERROR;
        }
        
        if (MEDmeshElementConnectivityRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL,
                                         geotype, MED_NODAL, MED_FULL_INTERLACE, connectivity) < 0) {
          MESSAGE("ERROR : cellconnectivity ...");
          ISCRUTE(geotype);
          free(connectivity);
          goto ERROR;
        }

        /* memory deallocation */
        free(connectivity);
        connectivity = NULL;
      }
    }
    

    /* read nodes coordinates changements step by step */
    for (it=1;it<nstep;it++) {
      
      if (MEDmeshComputationStepInfo(fid, meshname, it+1, 
                                     &numdt, &numit, &dt) < 0) {
        MESSAGE("ERROR : Computing step info ...");
        SSCRUTE(meshname);
        goto ERROR;
      }
      
      /* test changement : for nodes coordinates */
      if ((nnodes = MEDmeshnEntityWithProfile(fid, meshname, numdt, numit, 
                                              MED_NODE, MED_NONE,
                                              MED_COORDINATE, MED_NO_CMODE,
                                              MED_GLOBAL_PFLMODE, profilename, &profilesize,
                                              &coordinatechangement, &geotransformation)) < 0) {
        MESSAGE("ERROR : number of nodes ..."); 
        goto ERROR;
      }
      
      /* if only coordinates have changed, then read the new coordinates */
      /* to verify if there is a matrix transformation => UsesCase_MEDmesh12. */
      if (coordinatechangement && geotransformation) {
        if (MEDmeshNodeCoordinateWithProfileRd(fid, meshname, numdt, numit, 
                                               MED_GLOBAL_PFLMODE,profilename,
                                               MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,
                                               coordinates) < 0) {
          MESSAGE("ERROR : nodes coordinates ...");
          free(coordinates);
          goto ERROR;
        }
      }
      
    }
  }

  free(coordinates);

  ret=0;
 ERROR:

  /* close MED file */
  if (MEDfileClose(fid) < 0) {
    MESSAGE("ERROR : close file");             
    ret=-1; 
  } 

  
  return ret;
}

Pour ce qui concerne l'écriture des maillages avec déformation solide, il faut utiliser la routine MEDmeshNodeCoordinateTrsfWr / mmhtfw en passant en paramètre le pas de temps et ou le numéro d'ordre correspondant à l'étape et la matrice de transformation. Cette matrice comporte 7 valeurs réelles : les trois premières définissent la translation à appliquer selon l'ordre des axes définis pour le maillage et les quatres suivantes définissent une rotation phi par le quarternion (p4,p5-7) où p4 est le scalaire et p5-7 le vecteur décrit suivant l'ordre des axes définis pour le maillage. S'il y a moins de trois axes définis, les paramètres inutiles à la transformation doivent être à zéro.

/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 *  How to create an unstructured mesh 
 *
 *  Use case 9 : a 2D unstructured mesh with moving grid
 *  transformation   
 */

#include <med.h>
#define MESGERR 1
#include <med_utils.h>

#include <string.h>

int main (int argc, char **argv) {
  med_idt fid;
  const char meshname[MED_NAME_SIZE+1] = "2D unstructured mesh";
  const med_int spacedim = 2;
  const med_int meshdim = 2;
  const char axisname[2*MED_SNAME_SIZE+1] = "x               y               ";
  const char unitname[2*MED_SNAME_SIZE+1] = "cm              cm              ";
  const med_float initial_coordinates[30] = { 2.,1.,  7.,1.,  12.,1.,  17.,1.,  22.,1.,
                                              2.,6.,  7.,6.,  12.,6.,  17.,6.,  22.,6.,
                                              2.,11., 7.,11., 12.,11., 17.,11., 22.,11.};
  const med_int nnodes = 15;
  const med_int triaconnectivity[24] = { 1,7,6,   2,7,1,  3,7,2,   8,7,3,   
                                   13,7,8, 12,7,13, 11,7,12, 6,7,11 };
  const med_int ntria3 = 8;
  const med_int quadconnectivity[16] = {3,4,9,8,    4,5,10,9, 
                                        15,14,9,10, 13,8,9,14};
  const med_int nquad4 = 4;
  /* matrix transformation (step 1) : rotation about the Y-axis : 45 degrees */
  const med_float tansfMatrix_step1 [7] = { 0.0, 0.0, 0.0, 0.92388, 0.0, 0.38268, 0.0 };
  /* matrix transformation (step 2) : rotation about the Y-axis : 90 degrees */
  const med_float tansfMatrix_step2 [7] = { 0.0, 0.0, 0.0, 0.707,   0.0, 0.707,   0.0 };
  int ret=-1;
  
  /* open MED file */
  fid = MEDfileOpen("UsesCase_MEDmesh_9.med",MED_ACC_CREAT);
  if (fid < 0) {
    MESSAGE("ERROR : file creation ...");
    goto ERROR;
  }

  /* write a comment in the file */
  if (MEDfileCommentWr(fid,"A 2D unstructured mesh : 15 nodes, 12 cells") < 0) {
    MESSAGE("ERROR : write file description ...");
    goto ERROR;
  }

  /* mesh creation : a 2D unstructured mesh */
  if (MEDmeshCr(fid, meshname, spacedim, meshdim, MED_UNSTRUCTURED_MESH, 
                "A 2D structured mesh","",MED_SORT_DTIT,MED_CARTESIAN, axisname, unitname) < 0) {
    MESSAGE("ERROR : mesh creation ...");
    goto ERROR;
  }

  /* nodes coordinates in a cartesian axis in full interlace mode 
     (X1,Y1, X2,Y2, X3,Y3, ...) with no iteration and computation step 
  */
  if (MEDmeshNodeCoordinateWithProfileWr(fid, meshname, MED_NO_DT, MED_NO_IT, 0.0,
                                         MED_COMPACT_PFLMODE, MED_NO_PROFILE,
                                         MED_FULL_INTERLACE, MED_ALL_CONSTITUENT,
                                         nnodes, initial_coordinates) < 0) {
    MESSAGE("ERROR : nodes coordinates ...");
    goto ERROR;
  }

  /* cells connectiviy is defined in nodal mode */
  if (MEDmeshElementConnectivityWithProfileWr(fid, meshname, MED_NO_DT, MED_NO_IT, 0.0,
                                              MED_CELL, MED_TRIA3, MED_NODAL, 
                                              MED_COMPACT_PFLMODE, MED_NO_PROFILE,
                                              MED_FULL_INTERLACE, MED_ALL_CONSTITUENT, 
                                              ntria3, triaconnectivity) < 0) {
    MESSAGE("ERROR : triangular cells connectivity ...");
    goto ERROR;
  }

  if (MEDmeshElementConnectivityWithProfileWr(fid, meshname, MED_NO_DT, MED_NO_IT, 0.0,
                                              MED_CELL, MED_QUAD4, MED_NODAL, 
                                              MED_COMPACT_PFLMODE, MED_NO_PROFILE,
                                              MED_FULL_INTERLACE, MED_ALL_CONSTITUENT,  
                                              nquad4, quadconnectivity) < 0) {
    MESSAGE("ERROR : quadrangular cells connectivity ..."); 
    goto ERROR;
  }

  /* 
   * Mesh deformation (nodes coordinates) in 2 steps 
   * A rotation by step for each node
   */ 
  /* STEP 1 : dt1 = 5.5, it = 1*/
  if ( MEDmeshNodeCoordinateTrsfWr(fid, meshname, 1, 1, 5.5, tansfMatrix_step1) < 0) {
    MESSAGE("Erreur a l'ecriture de la transformation géométrique n°1");
    goto ERROR;
  }

  /* STEP 2 : dt2 = 8.9, it = 1*/
  if ( MEDmeshNodeCoordinateTrsfWr(fid, meshname, 2, 2, 8.9, tansfMatrix_step2 ) < 0) {
    MESSAGE("Erreur a l'ecriture de la transformation géométrique n°1");
    goto ERROR;
  }

  /* create family 0 : by default, all mesh entities family number is 0 */
  if (MEDfamilyCr(fid, meshname,MED_NO_NAME, 0, 0, MED_NO_GROUP) < 0) {
    MESSAGE("ERROR : create family ...");
    goto ERROR;
  }
  
  ret=0;
 ERROR:

  /* close MED file */
  if (MEDfileClose(fid)  < 0) {
    MESSAGE("ERROR : close file ...");
    ret=-1;
  }

  return ret;
}

A la lecture des maillages avec déformation solide, une fois la lecture du maillage initiale effectuée, il faut itérer sur les différentes étapes d'évolution présentes dans le maillage (le nombre d'étape est lue par les routines MEDmeshInfoByName / mmhmin ou MEDmeshInfo / mmhmii) et à chaque étape : récupérer les valeurs du pas de temps et du numéro d'itération avec la routine MEDmeshComputationStepInfo / mmhcsi ; déterminer la nature du changement parmi les cas possibles pré-cités avec la routine MEDmeshnEntityWithProfile / mmhnep et également vérifier la présence de la matrice de transformation ; lire la matrice de transformation avec la routine MEDmeshNodeCoordinateTrsfRd / mmhtfr.

Le cas d'utilisation suivant permet de lire de manière générique un maillage évolutif, à la fois s'il s'agit d'un maillage déformable à topologie constante ou d'un maillage avec déformation solide.

/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 *  Use case 12 : read a 2D unstructured mesh with moving grid (generic approach)
 */

#include <med.h>
#define MESGERR 1
#include <med_utils.h>

#include <string.h>

int main (int argc, char **argv) {
  med_idt fid;
  med_int nmesh;
  char meshname[MED_NAME_SIZE+1]="";
  char meshdescription[MED_COMMENT_SIZE+1]="";
  med_int meshdim;
  med_int spacedim;
  med_sorting_type sortingtype;
  med_int nstep;
  med_mesh_type meshtype;
  med_axis_type axistype;
  char *axisname;
  char *unitname;
  char dtunit[MED_SNAME_SIZE+1]="";
  med_float *coordinates = NULL;
  med_int ngeo = 0;
  med_int nnodes = 0;
  med_int *connectivity = NULL;
  med_bool coordinatechangement;
  med_bool geotransformation;
  med_bool matrixtransformation;
  med_int matrixsize;
  med_float matrix[7]={ 0, 0, 0, 0, 0, 0, 0};
  int i, it, j;
  med_int profilesize;
  char profilename[MED_NAME_SIZE+1]="";
  med_int numdt, numit;
  med_float dt;
  med_geometry_type geotype;
  med_geometry_type *geotypes = MED_GET_CELL_GEOMETRY_TYPE;
  int ret=-1;

  /* open MED file with READ ONLY access mode */
  fid = MEDfileOpen("UsesCase_MEDmesh_9.med",MED_ACC_RDONLY);
  if (fid < 0) {
    MESSAGE("ERROR : open file in READ ONLY ACCESS mode ...");
    goto ERROR;
  }


  /* read how many mesh in the file */
  if ((nmesh = MEDnMesh(fid)) < 0) {
    MESSAGE("ERROR : read how many mesh ...");
    goto ERROR;
  }

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

    /* read computation space dimension */
    if ((spacedim = MEDmeshnAxis(fid, i+1)) < 0) {
      MESSAGE("ERROR : read computation space dimension ...");
      goto ERROR;
    }
    
    /* memory allocation */
    if ((axisname  = (char*) malloc(MED_SNAME_SIZE*spacedim+1)) == NULL) {
      MESSAGE("ERROR : memory allocation ...");
      goto ERROR;
    }
    if ((unitname  = (char*) malloc(MED_SNAME_SIZE*spacedim+1)) == NULL) {
      MESSAGE("ERROR : memory allocation ...");
      goto ERROR;
    }

    /* read mesh informations : meshname, mesh dimension, mesh type ... */
    if (MEDmeshInfo(fid, i+1, meshname, &spacedim, &meshdim, &meshtype, meshdescription, 
                    dtunit, &sortingtype, &nstep,  
                    &axistype, axisname, unitname) < 0) {
      MESSAGE("ERROR : mesh info ...");
      free(axisname);
      free(unitname);
      goto ERROR;
    }
    free(axisname);
    free(unitname);


    /* read how many nodes in the mesh */
    if ((nnodes = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_NODE, MED_NONE,
                                 MED_COORDINATE, MED_NO_CMODE,&coordinatechangement,
                                 &geotransformation)) < 0) {
      MESSAGE("ERROR : number of nodes ...");
      goto ERROR;
    }
  
    /* read mesh nodes coordinates */
    if ((coordinates = (med_float*) malloc(sizeof(med_float)*nnodes*spacedim)) == NULL) {
      MESSAGE("ERROR : memory allocation ...");
      goto ERROR;
    }
    
    if (MEDmeshNodeCoordinateRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_FULL_INTERLACE,
                                coordinates) < 0) {
      MESSAGE("ERROR : nodes coordinates ...");
      free(coordinates);
      goto ERROR;
    }

    /* read all MED geometry cell types */
    for (it=1; it<= MED_N_CELL_FIXED_GEO; it++) {   

      geotype = geotypes[it];

      if ((ngeo = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL,geotype,
                                 MED_CONNECTIVITY, MED_NODAL, &coordinatechangement,
                                 &geotransformation)) < 0) {
        MESSAGE("ERROR : number of cell ...");
        ISCRUTE(geotype);
        goto ERROR;
      }
    
      if (ngeo) {
        /* read cells connectivity in the mesh */
        if ((connectivity = (med_int *) malloc(sizeof(med_int)*ngeo*(geotype%100))) == NULL) {
          MESSAGE("ERROR : memory allocation ...");
          goto ERROR;
        }
        
        if (MEDmeshElementConnectivityRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL,
                                         geotype, MED_NODAL, MED_FULL_INTERLACE, connectivity) < 0) {
          MESSAGE("ERROR : cellconnectivity ...");
          ISCRUTE(geotype);
          free(connectivity);
          goto ERROR;
        }

        /* memory deallocation */
        free(connectivity);
        connectivity = NULL;
      }
    }
    

    /* read nodes coordinates changements step by step */
    for (it=1;it<nstep;it++) {
      
      if (MEDmeshComputationStepInfo(fid, meshname, it+1, 
                                     &numdt, &numit, &dt) < 0) {
        MESSAGE("ERROR : Computing step info ...");
        SSCRUTE(meshname);
        goto ERROR;
      }
      
      /* test changement : for nodes coordinates */
      if ((nnodes = MEDmeshnEntityWithProfile(fid, meshname, numdt, numit, 
                                              MED_NODE, MED_NONE,
                                              MED_COORDINATE, MED_NO_CMODE,
                                              MED_GLOBAL_PFLMODE, profilename, &profilesize,
                                              &coordinatechangement, &geotransformation)) < 0) {
        MESSAGE("ERROR : number of nodes ..."); 
        goto ERROR;
      }
      
      /* if only coordinates have changed, then read the new coordinates */
      if (coordinatechangement && geotransformation) {  
        if (MEDmeshNodeCoordinateWithProfileRd(fid, meshname, numdt, numit, 
                                               MED_GLOBAL_PFLMODE,profilename,
                                               MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,
                                               coordinates) < 0) {
          MESSAGE("ERROR : nodes coordinates ...");
          free(coordinates);
          goto ERROR;
        }
      }

      if (coordinatechangement && ! geotransformation) {        

        matrixsize = MEDmeshnEntity(fid,meshname,numdt,numit,
                                    MED_NODE,MED_NONE,MED_COORDINATE_TRSF,MED_NODAL,&coordinatechangement, 
                                    &matrixtransformation);
        
        if (matrixsize < 0) {
          MESSAGE("ERROR : matrix transformation ...");
          goto ERROR;
        }
                
        if (matrixtransformation) {
          if ( MEDmeshNodeCoordinateTrsfRd(fid, meshname, numdt, numit, matrix) < 0 ) {
            MESSAGE("ERROR : read transformation matrix ...");
            goto ERROR;
          }
        }
      }
    }
  }
  free(coordinates);

  ret=0;
 ERROR:

  /* close MED file */
  if (MEDfileClose(fid) < 0) {
    MESSAGE("ERROR : close file");             
    ret=-1; 
  } 

  
  return ret;
}

Créer et lire une équivalence entre les entités d'un maillage

La notion d'équivalence permet de gérer des listes de correspondance mettant en relation deux entités de même type (deux noeuds, deux mailles, deux arêtes ou deux faces).

Une équivalence est identifiée par son nom (chaîne de MED_NAME_SIZE caractères) et possède également une description (chaîne d'au plus MED_COMMENT_SIZE). La routine MEDequivalenceCr / meqcre permet de créer une équivalence. L'écriture des équivalences est optionnelle : un fichier peut contenir de zéro à plusieurs équivalences. Une fois l'équivalence créée, il s'agit de lui associer des tableaux de correspondances entre les entités souhaitées. La routine MEDequivalenceCorrespondenceWr / meqcow permet d'écrire un tableau de correspondance dans une équivalence pour un type d'entité pour une étape d'évolution du maillage (<MED_NO_DT, MED_NO_IT> par défaut). Si cette entité correspond à un élément, il faut en plus préciser le type géométrique de l'élément.

Les correspondances entre entités sont stockées 2 à 2 en mémoire dans une équivalence : ainsi dans l'exemple suivant, le tableau de correspondances suivant {1,2,3,4,5,6} appliqué à des entités de type MED_TRIA3 (triangle à 3 noeuds), signifie qu'on a les 3 correspondances suivantes : entre le triangle numéro 1 et le triangle numéro 2, entre le triangle numéro 3 et le triangle numéro 4, entre le triangle numéro 5 et le triangle numéro 6.

/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */

/******************************************************************************
 * - Nom du fichier : test12.c
 *
 * - Description : ecriture d'une equivalence dans un maillage MED 
 *
 *****************************************************************************/

#include <med.h>
#define MESGERR 1
#include <med_utils.h>

#ifdef DEF_LECT_ECR
#define MODE_ACCES MED_ACC_RDWR
#elif DEF_LECT_AJOUT
#define MODE_ACCES MED_ACC_RDEXT
#else
#define MODE_ACCES MED_ACC_CREAT
#endif

int main (int argc, char **argv)


{
  med_idt fid;
  char maa[MED_NAME_SIZE+1]= "maa1";
  char equ[MED_NAME_SIZE+1] = "equivalence";
  char des[MED_COMMENT_SIZE+1] = "equivalence sur les mailles MED_TRIA3";
  med_int mdim = 3;
  med_int ncor = 3;
  med_int cor[6] = {1,2,3,4,5,6};
  char    nomcoo[3*MED_SNAME_SIZE+1] = "x               y               z               ";
  char    unicoo[3*MED_SNAME_SIZE+1] = "cm              cm              cm              ";


  /* Creation du fichier "test12.med" */
  if ((fid = MEDfileOpen("test12.med",MODE_ACCES)) < 0) {
    MESSAGE("Erreur a la creation du fichier test12.med");
    return -1;
  }

  if (MEDmeshCr( fid, maa, 3, 3, MED_UNSTRUCTURED_MESH,
                 "un maillage pour test12","s", MED_SORT_DTIT,
                 MED_CARTESIAN, nomcoo, unicoo) < 0) {
    MESSAGE("Erreur a la creation du maillage : "); SSCRUTE(maa);
    return -1;
  }

  /* Creation de l'equivalence */
  if (MEDequivalenceCr(fid,maa,equ,des) < 0) {
    MESSAGE("Erreur a la creation de l'equivalence");
    return -1;
  }

  /* Ecriture des sur les mailles MED_TRIA3 */
  if (MEDequivalenceCorrespondenceWr(fid,maa,equ,MED_NO_DT,MED_NO_IT,
                                     MED_CELL,MED_TRIA3,ncor,cor) < 0) {
    MESSAGE("Erreur a l'ecriture du tableau des correspondances");
    return -1;
  }
  /* Fermeture du fichier */
  if (MEDfileClose(fid) < 0) {
    MESSAGE("Erreur a la fermeture du fichier");
    return -1;
  }

  return 0;
}




A la lecture, l'accès aux équivalences dans un fichier peut se faire via un itérateur. La routine MEDnEquivalence / meqneq permet de lire le nombre d'équivalence dans un fichier. Il s'agit ensuite d'itérer sur toutes les équivalences et à chaque itération : la routine MEDequivalenceInfo / meqeqi lit les informations relatives à une équivalence (nom, description, nombre d'étape d'évolution du maillage, nombre de correspondance pour l'étape par défaut <MED_NO_DT,MED_NO_IT>) ; la routine MEDequivalenceCorrespondenceSize / meqcsz lit le nombre de correspondance par étape d'évolution du maillage ; la routine MEDequivalenceCorrespondenceRd / meqcor permet de lire un tableau de correspondance pour un type d'entité pour une étape d'évolution du maillage.

A noter également l'existence de la routine MEDequivalenceComputingStepInfo / meqcsi qui permet de lire les informations relatives à une équivalence pour une étape d'évolution du maillage donnée.

Le cas d'utilisation suivant propose une lecture générique de toutes les équivalences qu'il est possible de trouver dans un fichier MED.

/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */

/******************************************************************************
 * - Nom du fichier : test13.c
 *
 * - Description : lecture des equivalences d'un maillage MED.
 *
 *****************************************************************************/

#include <med.h>
#define MESGERR 1
#include <med_utils.h>


#ifdef DEF_LECT_ECR
#define MODE_ACCES MED_ACC_RDWR
#elif DEF_LECT_AJOUT
#define MODE_ACCES MED_ACC_RDEXT
#else
#define MODE_ACCES MED_ACC_CREAT
#endif

int main (int argc, char **argv)


{
  med_err ret = 0;
  med_idt fid = 0;
  char    maa[MED_NAME_SIZE+1]="";
  med_int mdim=0,sdim=0;
  med_int nequ=0,ncor=0,nstep=0,nocstpncor=0;
  med_int *cor;
  char equ[MED_NAME_SIZE+1]   ="";
  char des[MED_COMMENT_SIZE+1]="";

  int i,j,k;
  med_mesh_type type;
  med_sorting_type sort;
  char desc[MED_COMMENT_SIZE+1];
  char dtunit[MED_SNAME_SIZE+1]="";
  char nomcoo[3*MED_SNAME_SIZE+1];
  char unicoo[3*MED_SNAME_SIZE+1];
  med_axis_type rep;

  med_geometry_type *typmai = MED_GET_CELL_GEOMETRY_TYPE;
  med_geometry_type *typfac = MED_GET_FACE_GEOMETRY_TYPE;
  med_geometry_type *typare = MED_GET_EDGE_GEOMETRY_TYPE;

  if (argc != 2) {
    MESSAGE("Il faut passer un fichier MED en paramètre");
    return -1;
  }

  /* Ouverture du fichier passe en argument en lecture seule */
  if ((fid = MEDfileOpen(argv[1],MED_ACC_RDONLY)) < 0) {
    MESSAGE("Erreur a l'ouverture du fichier : "); SSCRUTE(argv[1]);
    return -1;
  }

  if ((sdim=MEDmeshnAxis(fid, 1)) <0) {
    MESSAGE("Erreur a la lecture de la dimension de l'espace du maillage :");
    SSCRUTE(maa);
    return -1;
  }

  /* Lecture des infos concernant le premier maillage */
  if ( MEDmeshInfo( fid, 1,  maa, &sdim, &mdim, &type, desc, dtunit, &sort,
                    &nstep,  &rep, nomcoo,unicoo) < 0 ) {
    MESSAGE("Erreur a la lecture des informations sur le maillage : ");SSCRUTE(maa);
    return -1;
  } else {
    printf("Maillage de nom : |%s| , de dimension : "IFORMAT" , et de type %d\n",maa,mdim,type);
    printf("\t -Dimension de l'espace : "IFORMAT"\n",sdim);
    printf("\t -Description du maillage : %s\n",desc);
    printf("\t -Noms des axes : |%s|\n",nomcoo);
    printf("\t -Unités des axes : |%s|\n",unicoo);
    printf("\t -Type de repère : %d\n",rep);
    printf("\t -Nombre d'étapes de calcul : "IFORMAT"\n",nstep);
    printf("\t -Unité des dates : |%s|\n",dtunit);
  }

  /* Lecture du nombre d'equivalence */
  if ((nequ = MEDnEquivalence(fid,maa)) < 0) {
    MESSAGE("Erreur a la lecture du nombre d'equivalence");
    return -1;
  }
  printf("Nombre d'equivalences : "IFORMAT" \n",nequ);

  /* Lecture de toutes les equivalences du maillage */
  if (nequ > 0)
    for (i = 0;i<nequ;i++) {
      printf("Equivalence numero : %d \n",i+1);

      /* Lecture des infos sur l'equivalence */
      if (MEDequivalenceInfo(fid,maa,i+1,equ,des,&nstep,&nocstpncor) < 0) {
        MESSAGE("Erreur a la lecture de l'equivalence d'indice");
        ISCRUTE_int(i+1);
        return -1;
      }
      printf("Nom de l'equivalence: |%s| \n",equ);
      printf("Description de l'equivalence : |%s| \n",des);
      printf("Nombre d'étapes de calcul : "IFORMAT" \n",nstep);
      printf("Nombre de correspondances pour l'étape de calcul MED_NO_DT,MED_NO_IT : "IFORMAT" \n",nocstpncor);

      /* Lecture des correspondances sur les differents types d'entites */

      /* Les noeuds */
      if ( MEDequivalenceCorrespondenceSize(fid,maa,equ,MED_NO_DT,MED_NO_IT,MED_NODE,MED_NONE,&ncor) < 0) {
        MESSAGE("Erreur a la lecture du nombre de correspondance sur les noeuds");
        return -1;
      }
      printf("Il y a "IFORMAT" correspondances sur les noeuds \n",ncor);
      if (ncor > 0) {
        cor = (med_int*) malloc(sizeof(med_int)*ncor*2);
        if (MEDequivalenceCorrespondenceRd(fid,maa,equ,MED_NO_DT,MED_NO_IT,
                                           MED_NODE,MED_NONE,cor) < 0) {
          MESSAGE("Erreur a la lecture des correspondances sur les noeuds");
          ret = -1;
        }
        if (ret == 0)
          for (j=0;j<ncor;j++)
            printf("Correspondance %d : "IFORMAT" et "IFORMAT" \n",j+1,*(cor+2*j),
                   *(cor+2*j+1));
        free(cor);
      }

      /* Les mailles : on ne prend pas en compte les mailles 3D */
      if (ret == 0)
        for (j=1;j<=MED_N_CELL_FIXED_GEO;j++) {

          if ( MEDequivalenceCorrespondenceSize(fid,maa,equ,MED_NO_DT,MED_NO_IT,MED_CELL,typmai[j],&ncor) < 0) {
            MESSAGE("Erreur a la lecture du nombre de correspondance sur les mailles : ");
            SSCRUTE(MED_GET_CELL_GEOMETRY_TYPENAME[j]);
            return -1;
          }
          printf("Il y a "IFORMAT" correspondances sur les mailles %s \n",ncor,
                 MED_GET_CELL_GEOMETRY_TYPENAME[j]);
          if (ncor > 0) {
            cor = (med_int*) malloc(sizeof(med_int)*ncor*2);
            if (MEDequivalenceCorrespondenceRd(fid,maa,equ,MED_NO_DT,MED_NO_IT,
                                               MED_CELL,typmai[j],cor) < 0) {
              MESSAGE("Erreur a la lecture des correspondances sur les mailles : ");
              SSCRUTE(MED_GET_CELL_GEOMETRY_TYPENAME[j]);
              ret = -1;
            }
            if (ret == 0)
              for (k=0;k<ncor;k++)
                printf("Correspondance %d : "IFORMAT" et "IFORMAT" \n",k+1,*(cor+2*k),
                       *(cor+2*k+1));
            free(cor);
          }
        }

      /* Les faces */
      if (ret == 0)
        for (j=1;j<=MED_N_FACE_FIXED_GEO;j++) {
          if ( MEDequivalenceCorrespondenceSize(fid,maa,equ,MED_NO_DT,MED_NO_IT,
                                                MED_DESCENDING_FACE,typfac[j],&ncor) < 0) {
            MESSAGE("Erreur a la lecture du nombre de correspondance sur les faces : ");
            SSCRUTE(MED_GET_FACE_GEOMETRY_TYPENAME[j]);
            return -1;
          }
          printf("Il y a "IFORMAT" correspondances sur les faces %s \n",ncor,
                 MED_GET_FACE_GEOMETRY_TYPENAME[j]);
          if (ncor > 0) {
            cor = (med_int*) malloc(sizeof(med_int)*ncor*2);
            if (MEDequivalenceCorrespondenceRd(fid,maa,equ,MED_NO_DT,MED_NO_IT,
                                               MED_DESCENDING_FACE,typfac[j],cor) < 0) {
              MESSAGE("Erreur a la lecture des correspondances sur les faces : ");
              SSCRUTE(MED_GET_FACE_GEOMETRY_TYPENAME[j]);
              ret = -1;
            }
            if (ret == 0)
              for (k=0;k<ncor;k++)
                printf("Correspondance %d : "IFORMAT" et "IFORMAT" \n",k+1,*(cor+2*k),
                       *(cor+2*k+1));
            free(cor);
          }
        }

      /*  Les aretes */
      if (ret == 0)
        for (j=1;j<=MED_N_EDGE_FIXED_GEO;j++) {
          if ( MEDequivalenceCorrespondenceSize(fid,maa,equ,MED_NO_DT,MED_NO_IT,
                                                MED_DESCENDING_EDGE,typare[j],&ncor) < 0) {
            MESSAGE("Erreur a la lecture du nombre de correspondance sur les aretes : ");
            SSCRUTE(MED_GET_EDGE_GEOMETRY_TYPENAME[j]);
            return -1;
          }
          printf("Il y a "IFORMAT" correspondances sur les aretes %s \n",ncor,
                 MED_GET_EDGE_GEOMETRY_TYPENAME[j]);
          if (ncor > 0) {
            cor = (med_int*) malloc(sizeof(med_int)*ncor*2);
            if (MEDequivalenceCorrespondenceRd(fid,maa,equ,MED_NO_DT,MED_NO_IT,
                                               MED_DESCENDING_EDGE,typare[j],cor) < 0) {
             MESSAGE("Erreur a la lecture des correspondances sur les faces : ");
             SSCRUTE(MED_GET_EDGE_GEOMETRY_TYPENAME[j]);
             ret = -1;
           }
           if (ret == 0)
             for (k=0;k<ncor;k++)
               printf("Correspondance %d : "IFORMAT" et "IFORMAT" \n",k+1,*(cor+2*k),
                      *(cor+2*k+1));
           free(cor);
          }
        }

    }

  /* Fermeture du fichier */
  if (MEDfileClose(fid) < 0) {
    MESSAGE("Erreur a la fermeture du fichier ");
    return -1;
  }

  return ret;
}




Créer et lire un maillage avec des éléments de structure

MED permet de créer des modèles d'éléments de structure. Un modèle d'élément est propre à un fichier qui doit être celui de(s) maillage(s) de calcul qui utilisent le modèle. Il peut y avoir plusieurs modèles d'éléments de structures dans un même fichier. Une fois le modèle défini, l'élément de structure devient un nouveau type d'élément d'un maillage de calcul au même titre que les autres types d'éléments pré-définis dans le modèle.

Le modèle MED réserve des noms de modèles pour les particules (MED_PARTICLE_NAME), les billes (MED_BALL_NAME) et les poutres (MED_BEAM_NAME). Cette liste de noms réservés est amenée à s'étoffer au fil des versions de MED, de fait tous les noms de modèle commençant par  MED_  sont également réservés. A chaque nom de modèle réservé ou fixé par l'utilisateur est associé un numéro de type géométrique unique au fichier. Ce numéro complète les numéros existants pour les types géométriques éléments finis. Le numéro de type d'un élément de structure est utilisable comme celui des types géométriques classiques pour s'informer de la présence du type d'élément dans un maillage de calcul. Le type d'entité de ce type d'élément est MED_STRUCT_ELEMENT.

Un modèle de structure utilisé dans un fichier doit être complètement défini dans ce fichier. Ainsi les maillages et les champs s'appuyant sur des élements de ce modèle pourront être relus par tout code s'intéressant aux éléments de structure. La description d'un modèle d'élément de structure peut s'appuyer sur un maillage support.

Si le modèle ne contient pas de maillage support, chaque élément de structure associé au modèle, s'appuie sur les noeuds du maillage de calcul pour se positionner. C'est le cas par exemple du modèle pré-défini des particules. Les coordonnées de ces noeuds peuvent évoluer au cours du temps selon le principe des maillages évolutifs présentés précédemment.

Un maillage support contient 1 ou plusieurs noeuds et éventuellement des mailles. La connectivité des éléments de structure y est uniquement décrite en mode nodal. Les noeuds d'un maillage support sont définis indépendamment des maillages de calcul. Ces noeuds ne sont pas référencés dans les maillages de calculs. Les coordonnées des noeuds sont définies dans un espace de dimension égale à celle de l'élément de structure. Le repère de coordonnées est propre à la description du modèle de l'élément. Les mailles définies dans un maillage support sont indépendantes des maillages de calcul et ne sont pas référencées dans les maillages de calcul. S'il y a des mailles dans le maillage support, la connectivité des éléments de structure référence des numéros de mailles dans les maillages de calcul. Il ne peut y avoir qu'un seul type géométrique de maille dans un maillage support. Dans un maillage support, il est pas utile d'écrire les numéros de familles (toutes les entités sont rattachées à la famille 0 par défaut), les numéros optionnels, les noms optionnels des entités du maillage. Un maillage support ne peut contenir de polygones ou polyèdres quelconques.

Les caractéristiques d'un élément de structure sont décrites par des attributs. Il existe deux types d'attributs caractéristiques : des attributs caractéristiques à valeur constante pour tous les éléments du modèle (ou attributs caractéristiques du modèle), des attributs caractéristiques à valeur variable selon les éléments du modèle (la valeur est alors définie au niveau des éléments dans les maillage de calcul). Les attributs caractéristiques sont typé par les types MED standards (entier, réel, chaîne de caractères de taille MED_NAME_SIZE). Un attribut peut comporter plusieurs composantes au même titre qu'un champ.

La création d'un modèle d'élément de structure se fait avec la routine MEDstructElementCr / msecre. Un modèle est identifié par son nom qui est une chaîne de MED_NAME_SIZE caractères. La création d'un attribut caractéristique à valeur variable se fait avec la routine MEDstructElementVarAttCr / msevac. La création d'un attribut caractéristique du modèle se fait avec les routines MEDstructElementConstAttWr / mseraw, mseiaw, msesaw. La routine MEDmeshStructElementVarAttWr / mmhraw, mmhiaw, mmhsaw permet d'écrire les valeurs d'un attribut à valeur variable, l'appel à cette routine se faisant au moment de la création d'un maillage de calcul. Les routines MEDstructElementConstAttWr / mseraw, mseiaw, msesaw et MEDstructElementConstAttWithProfileWr / mserpw, mseipw, msespw permettent d'écrire les valeurs d'un attribut constant respectivement sans et avec un profil.

La création d'un maillage support se fait avec une routine spécifique MEDsupportMeshCr / msmcre. L'écriture des coordonnées des noeuds et de la connectivité des mailles se fait avec les mêmes routines que celles utilisées pour les maillages de calcul. Un maillage support est identifié par son nom qui est une chaîne de MED_NAME_SIZE caractères.

Le cas d'utilisation suivant définit 3 modèles d'éléments de structure différents pour les particules, les billes et les poutres. Les deux derniers modèles s'appuient sur des maillages support également définis dans le fichier. Des éléments de structure qui correspondent à ces modèles sont finalement utilisés dans un maillage de calcul.

/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * StructElement use case 1 : write struct elements model in a file
 * STEP 1 : suppport mesh creation
 * STEP 2 : struct element model creation
 * STEP 3 : computation mesh creation
 */

#include <med.h>
#define MESGERR 1
#include <med_utils.h>

#include <string.h>

int main (int argc, char **argv) {
  med_idt fid;
  char elementname[MED_NAME_SIZE+1]="";
  const char ballsupportname[MED_NAME_SIZE+1]="BALL_SUPPORT_MESH";
  const char beamsupportname[MED_NAME_SIZE+1]="BEAM_SUPPORT_MESH";
  const char computmeshname[MED_NAME_SIZE+1]="COMPUT_MESH";
  const char beamsectionname[MED_NAME_SIZE+1]="BEAM_SECTION_MESH";
  const med_int elementdim = 3;
  med_int nnode;
  med_geometry_type geotype=MED_NONE;
  med_int ncomp;
  const med_float ballmeshnodescoo[3] = {0.0, 0.0, 0.0 };
  const med_float beammeshnodescoo[3*7] = {0.0,0.0,0.0,
                                           0.0,0.0,2.0,
                                           0.0,0.0,4.0,
                                           0.0,0.0,5.0,
                                           0.0,0.0,7.0,
                                           0.0,0.0,10.0,
                                           0.0,0.0,11.0 };
  const med_float beamsectioncoo[9*3] = {-0.2,-0.2,0.0,
                                         0.0,-0.2,0.0,
                                         0.2,-0.2,0.0,
                                         -0.2, 0.0,0.0,
                                         0.0, 0.0,0.0,
                                         0.2, 0.0,0.0,
                                         -0.2, 0.2,0.0,
                                         0.0, 0.2,0.0,
                                         0.2, 0.2,0.0 };
  const med_int seg2connectivity[2*6] = {1,2, 2,3, 3,4, 4,5, 5,6, 6,7};
  med_int spacedim, meshdim,nseg2;
  /*                                         123456789012345612345678901234561234567890123456 */
  const char axisname[3*MED_SNAME_SIZE+1] = "x               y               z               ";
  const char unitname[3*MED_SNAME_SIZE+1] = "cm              cm              cm              ";
  const med_float attvalue[6] = {0.2,0.3,0.4,0.4,0.3,0.2};
  /*                                            1234567890123456789012345678901234567890123456789012345678901234        */
  const char attprovalue[2*MED_NAME_SIZE+1] = {"EXTREMITY_1_____________________________________________________" \
                                               "EXTREMITY_2_____________________________________________________" };
  const char profilename[MED_NAME_SIZE+1] = "EXTREMITY_PROFILE_NAME";
  const med_int profilesize = 2;
  const med_int profile[2] = {1,6};
  const med_float meshcoo[3*12] = { 0.0, 0.0, 0.0,
                                    1.1, 1.1, 1.1,
                                    2.2, 2.2, 2.2,
                                    10., 10., 10.,
                                    12., 12., 12.,
                                    60., 20., 20.,
                                    70., 20., 20.,
                                    80., 20., 20.,
                                    90., 20., 20.,
                                    100., 20., 20.,
                                    110., 20., 20.,
                                    120., 20., 20.
  };
  const med_int beamconnectivity[12] = {  6,7,
                                          7,8,
                                          8,9,
                                          9,10,
                                          10,11,
                                          11,12 };
  med_int nentity;
  const med_int labels[3] = { 1, 2, 3 }; /* nodes numbers */
  const med_int ballconnectivity[2] = { 4, 5 }; /* nodes numbers */
  const med_float balldiameter[2] = { 2.0, 5.8 };
  const med_int nquad4=4;
  const med_int beamsectionconnectivity[4*4] = { 4,5,2,1,
                                                 5,6,3,2,
                                                 7,8,5,4,
                                                 8,9,6,5};
  int ret=-1;
  
  /* file creation */
  fid = MEDfileOpen("UsesCase_MEDstructElement_1.med",MED_ACC_CREAT);
  if (fid < 0) {
    MESSAGE("ERROR : file creation");
    goto ERROR;
  }

  /* STEP 1 : support meshes creation */
  spacedim =  3;
  meshdim = 3;

  /* Mesh 1 : support mesh for ball model */
  if (MEDsupportMeshCr(fid, ballsupportname, spacedim, meshdim, "Support mesh for a ball model",
                       MED_CARTESIAN, axisname, unitname) < 0) {
    MESSAGE("ERROR : creating a support mesh ...");
    goto ERROR;
  }
  /* 1 node and no cell in the mesh */
  nnode = 1;
  if (MEDmeshNodeCoordinateWr(fid, ballsupportname, MED_NO_DT, MED_NO_IT, 0.0,
                              MED_FULL_INTERLACE, nnode, ballmeshnodescoo) < 0) {
    MESSAGE("ERROR : write nodes coordinates ...");
    goto ERROR;
  }

  /* Mesh 2 :support mesh for beam model */
  if (MEDsupportMeshCr(fid, beamsupportname, spacedim, meshdim, "Support mesh for a beam model",
                       MED_CARTESIAN, axisname, unitname) < 0) {
    MESSAGE("ERROR : creating a support mesh ...");
    goto ERROR;
  }
  /* 7 nodes and 6 MED_SEG2 */
  nnode = 7;
  if (MEDmeshNodeCoordinateWr(fid, beamsupportname, MED_NO_DT, MED_NO_IT, 0.0,
                              MED_FULL_INTERLACE, nnode,  beammeshnodescoo) < 0) {
    MESSAGE("ERROR : write nodes coordinates ...");
    goto ERROR;
  }
  nseg2 = 6;
  if (MEDmeshElementConnectivityWr(fid, beamsupportname, MED_NO_DT, MED_NO_IT, 0.0, MED_CELL, MED_SEG2,
                                   MED_NODAL, MED_FULL_INTERLACE, nseg2, seg2connectivity) < 0) {
    MESSAGE("ERROR : write cells connectivity ...");
    goto ERROR;
  }

  /* Mesh 3 : support mesh to define a section for integration points of
     a struct element */
  if (MEDsupportMeshCr(fid, beamsectionname, spacedim, meshdim, "Support mesh for a section of the beam model",
                       MED_CARTESIAN, axisname, unitname) < 0) {
    MESSAGE("ERROR : creating a support mesh ...");
    goto ERROR;
  }

  nnode = 9;
  if (MEDmeshNodeCoordinateWr(fid, beamsectionname, MED_NO_DT, MED_NO_IT, 0.0,
                              MED_FULL_INTERLACE, nnode, beamsectioncoo) < 0) {
    MESSAGE("ERROR : write nodes coordinates ...");
    goto ERROR;
  }

  if (MEDmeshElementConnectivityWr(fid, beamsectionname, MED_NO_DT, MED_NO_IT, 0.0, MED_CELL, MED_QUAD4,
                                   MED_NODAL, MED_FULL_INTERLACE, nquad4, beamsectionconnectivity) < 0) {
    MESSAGE("ERROR : write cells connectivity ...");
    goto ERROR;
  }

  /* STEP 2 */
  /* particle model creation : no support mesh */
  strcpy(elementname,MED_PARTICLE_NAME);
  if ((geotype = MEDstructElementCr(fid, elementname, elementdim, MED_NO_MESHNAME,
                                    MED_NONE,MED_NONE)) < 0) {
    MESSAGE("ERROR : creating struct element");
    goto ERROR;
  }
  ncomp=1;
  if (MEDstructElementVarAttCr(fid, elementname,
                               MED_PARTICLE_LABEL, MED_ATT_INT, ncomp) < 0) {
    MESSAGE("ERROR : creating struct element");
    goto ERROR;
  }

  /* ball model creation */
  strcpy(elementname,MED_BALL_NAME);
  if ((geotype = MEDstructElementCr(fid, elementname, elementdim, ballsupportname,
                                    MED_NODE,MED_NONE)) < 0) {
    MESSAGE("ERROR : creating struct element");
    goto ERROR;
  }
  ncomp=1;
  if (MEDstructElementVarAttCr(fid, elementname,
                               MED_BALL_DIAMETER, MED_ATT_FLOAT64, ncomp) < 0) {
    MESSAGE("ERROR : creating struct element");
    goto ERROR;
  }


  /* A beam */
  strcpy(elementname,MED_BEAM_NAME);
  if ((geotype = MEDstructElementCr(fid, elementname, elementdim, beamsupportname,
                                    MED_CELL,MED_SEG2)) < 0) {
    MESSAGE("ERROR : creating struct element");
    goto ERROR;
  }
  ncomp=1;
  /* a first constant attribute */
  if (MEDstructElementConstAttWr(fid, elementname,
                                 MED_BEAM_THICKNESS, MED_ATT_FLOAT64, ncomp,
                                 MED_CELL,(void*) attvalue) < 0) {
    MESSAGE("ERROR : creating struct element");
    goto ERROR;
  }
  /* a second constant attribute defined with a profile for the first and the
     last segment */
  /* create the profile */
    if (MEDprofileWr(fid, profilename, profilesize, profile ) < 0) {
    MESSAGE("ERROR : create profile ...");
    goto ERROR;
  }
  /* write the constant attribute */
  if (MEDstructElementConstAttWithProfileWr(fid,
                                            elementname,
                                            "BEAM_EXTREMITIES_LABELS",
                                            MED_ATT_NAME,
                                            ncomp,
                                            MED_CELL,
                                            profilename,
                                            (void*) attprovalue) < 0) {
    MESSAGE("ERROR : creating struct element");
    goto ERROR;
  }

  /* STEP 3 : Computation mesh creation */

  /* mesh creation */
  if (MEDmeshCr(fid, computmeshname, spacedim, meshdim,  MED_UNSTRUCTURED_MESH,
                "Computation mesh", "s", MED_SORT_DTIT,
                MED_CARTESIAN, axisname, unitname) < 0) {
    MESSAGE("ERROR : creating computation mesh ...");
    goto ERROR;
  }

  /* mesh node creation */
  nnode = 12;
  if (MEDmeshNodeCoordinateWr(fid, computmeshname, MED_NO_DT, MED_NO_IT, MED_UNDEF_DT,
                              MED_FULL_INTERLACE, nnode, meshcoo) < 0) {
    MESSAGE("ERROR : writing nodes coordinates ...");
    goto ERROR;
  }

  /* 1 beam */
  nentity = 1;
  SSCRUTE(elementname);
  geotype = MEDstructElementGeotype(fid,elementname);
  ISCRUTE(geotype);

  if (MEDmeshElementConnectivityWr(fid,computmeshname, MED_NO_DT, MED_NO_IT, MED_UNDEF_DT,
                                   MED_STRUCT_ELEMENT, geotype, MED_NODAL,
                                   MED_FULL_INTERLACE, nentity, beamconnectivity) < 0 ) {
    MESSAGE("ERROR : beam connectivity ...");
    goto ERROR;
  }

  /* Get the dynamic geometry type of each struct element model.
     Then for each type, write the connectivity and variable(s) attribute(s) */

  /* 3 particles in the mesh */
  strcpy(elementname,MED_PARTICLE_NAME);
  geotype = MEDstructElementGeotype(fid,elementname);
  nentity = 3;
  ISCRUTE(geotype);
  if (MEDmeshElementConnectivityWr(fid, computmeshname, MED_NO_DT, MED_NO_IT, 0.0, 
                                   MED_STRUCT_ELEMENT, geotype , MED_NODAL, MED_FULL_INTERLACE,
                                   nentity, 0) < 0) {
    MESSAGE("ERROR : writing particles connectivity ...");
    goto ERROR;
  }

  /* no support mesh => no connectivity, the particles are localized with an association between
     the mesh nodes and the label attribute defined in the struct model */
  if (MEDmeshStructElementVarAttWr(fid, computmeshname, MED_NO_DT, MED_NO_IT,
                                   geotype, MED_PARTICLE_LABEL,
                                   nentity, labels) < 0 ) {
    MESSAGE("ERROR : writing variable attributes  ...");
    goto ERROR;
  }


  /* 2 balls */
  strcpy(elementname,MED_BALL_NAME);
  nentity = 2;
  geotype = MEDstructElementGeotype(fid,elementname);
  if (MEDmeshElementConnectivityWr(fid,computmeshname, MED_NO_DT, MED_NO_IT, MED_UNDEF_DT,
                                   MED_STRUCT_ELEMENT, geotype, MED_NODAL,
                                   MED_FULL_INTERLACE, nentity, ballconnectivity) < 0 ) {
    MESSAGE("ERROR : writing balls connectivity");
    goto ERROR;
  }

  /* variable attribute : write ball diameter */
  if (MEDmeshStructElementVarAttWr(fid, computmeshname, MED_NO_DT, MED_NO_IT,
                                   geotype, MED_BALL_DIAMETER,
                                   nentity, balldiameter) < 0 ) {
    MESSAGE("ERROR : writing variable attributes ...");
    goto ERROR;
  }


  ret=0;
 ERROR:

  /* close file */
  if (MEDfileClose(fid) < 0) {
    MESSAGE("ERROR : file closing");
    ret=-1;
  }

  return ret;
}

La routine MEDstructElementInfoByName / msesin permet de récupérer les informations relatives à un modèle d'élément de structure dont on connaît le nom. Un autre mode d'accès en lecture consiste à utiliser la routine MEDnStructElement / msense pour lire le nombre de modèle dans un fichier. Il s'agit ensuite d'itérer sur ces modèles. La routine MEDstructElementInfo / msesei permet de lire à chaque itération les informations relatives à un modèle d'élément de structure. Pour ce qui concerne la lecture des attributs constants, la routine MEDstructElementConstAttInfo / msecai permet de lire les informations relatives à ce type d'attribut et les routines MEDstructElementConstAttRd / mserar, mseiar, msesar permettent de lire les valeurs d'un attribut constant sans et avec un profil. Pour ce qui concerne les attributs variables, la routine MEDstructElementVarAttInfo / msevai permet de lire les informations relatives à ce type d'attribut et les routines MEDmeshStructElementVarAttRd / mmhrar, mmhiar, mmhsar permettent de lire les valeurs d'un attribut variable.

A noter également l'existence : de la routine MEDstructElementName / msesen qui à partir du numéro de type géométrique de l'élément de structure, fournit le nom de cet élément ; de la routine MEDstructElementGeotype / msesgt qui à partir du nom de l'élément renvoie son type. Enfin la routine MEDstructElementAttSizeof / mseasz renvoie la taille en octets du type élémentaire d'un attribut constant ou variable, ce qui permet d'allouer correctement la taille des tableaux pour lire les valeurs des attributs.

La routine MEDsupportMeshInfoByName / msmsni permet de récupérer les informations relatives à un maillage support dont on connaît le nom. Un autre mode d'accès en lecture consiste à utiliser la routine MEDnSupportMesh / msmnsm afin de lire le nombre de maillage support dans un fichier. Il s'agit ensuite d'itérer sur ces maillages support et à chaque itération de lire les informations relative au maillage avec la routine MEDsupportMeshInfo / msmsmi. La lecture des coordonnées des noeuds et de la connectivité des mailles se fait avec les mêmes routines que celles utilisées pour les maillages de calcul.

Ce cas d'utilisation montre comment à partir d'un maillage de calcul, accéder aux modèles d'éléments de structure et aux maillages supports.

/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <med.h>
#define MESGERR 1
#include <med_utils.h>

#include <string.h>

/* 
 * StructElement use case 3 : read struct element models in a file from a computation mesh 
 */

int main (int argc, char **argv) {
  med_idt fid;
  med_int nmodels, nsmesh;
  int i,j;
  char elementname[MED_NAME_SIZE+1]="";
  char supportmeshname[MED_NAME_SIZE+1]="";
  const char computmeshname[MED_NAME_SIZE+1]="COMPUT_MESH";
  med_geometry_type *geotype;
  med_entity_type entitype;
  med_int elementdim;
  med_int nnode,ncell;
  med_geometry_type geocelltype;
  med_bool anyprofile=0;
  med_int nconstatt, *nvaratt=NULL;
  char attname[MED_NAME_SIZE+1]="";
  char profilename[MED_NAME_SIZE+1]="";
  med_attribute_type atttype;
  med_int nattcomp;
  med_entity_type attentitype;
  med_int profilesize;
  med_float *value=NULL;
  med_int size=0;
  med_int meshdim, spacedim;
  char description[MED_COMMENT_SIZE+1]="";
  char axisname[3*MED_SNAME_SIZE+1]="";
  char axisunit[3*MED_SNAME_SIZE+1]="";
  med_axis_type axistype;
  med_float *coordinates=NULL;
  med_bool coordinatechangement;
  med_bool geotransformation;
  med_int nseg2;
  med_int *seg2connectivity=NULL;
  med_int nentities=0;
  med_sorting_type sortingtype;
  med_mesh_type meshtype;
  med_int nstep;
  char dtunit[MED_SNAME_SIZE+1]="";
  char unitname[2*MED_SNAME_SIZE+1]="";
  int ret=-1;

  /* open file */
  fid = MEDfileOpen("UsesCase_MEDstructElement_1.med",MED_ACC_RDONLY);
  if (fid < 0) {
    MESSAGE("ERROR : file creation ...");
    goto ERROR;
  }

  /* 
   * ... In this case, we know that the MED file has only one mesh, 
   * a real code working would check ... 
   */
  /* read mesh informations : mesh dimension, space dimension ... */
  if (MEDmeshInfoByName(fid, computmeshname, &spacedim, &meshdim, &meshtype, description, 
                        dtunit, &sortingtype, &nstep, &axistype, axisname, unitname) < 0) {
    MESSAGE("ERROR : mesh info ...");
    goto ERROR;
  }

  /* read how many struct element models in the mesh ? */
  if ((nmodels = MEDmeshnEntity(fid, computmeshname, MED_NO_DT, MED_NO_IT, MED_STRUCT_ELEMENT, MED_GEO_ALL,
                              MED_UNDEF_DATATYPE, MED_NO_CMODE,&coordinatechangement,
                              &geotransformation)) < 0) {
    MESSAGE("ERROR : number of nodes ...");
    goto ERROR;
  }

  geotype = (med_geometry_type *) malloc(sizeof(med_geometry_type)*nmodels);
  nvaratt = (med_int *) malloc(sizeof(med_int)*nmodels);

  /* Get the name and the geotype of each struct element model used in the computation mesh.
     For each struct element geotype read the connectivity and the attribute(s) 
     The mesh support may be read if needed.
  */
  for (i=0;i<nmodels;i++) {

    /* read the geotype */
    if (MEDmeshEntityInfo(fid, computmeshname, MED_NO_DT, MED_NO_IT, MED_STRUCT_ELEMENT,i+1,elementname,(geotype+i)) < 0) {
      MESSAGE("ERROR : name and type of MED_STRUCT_ELEMENT ...");
      goto ERROR;
    }

    /* read how many MED_STRUCT_ELEMENT of type *(geotype+i) there is in the mesh */
    if ((nentities = MEDmeshnEntity(fid, computmeshname, MED_NO_DT, MED_NO_IT, MED_STRUCT_ELEMENT,*(geotype+i),
                                    MED_CONNECTIVITY, MED_NODAL, &coordinatechangement,
                                    &geotransformation)) < 0) {
      MESSAGE("ERROR : number of MED_STRUCT_ELEMENT ...");
      goto ERROR;
    }

    /* read informations about the model */
    if (MEDstructElementInfoByName(fid, elementname, geotype+i, &elementdim,
                                   supportmeshname, &entitype, &nnode, &ncell,
                                   &geocelltype, &nconstatt, &anyprofile, nvaratt+i) < 0) {
      MESSAGE("ERROR : struct element models information ...");
      goto ERROR;
    }
    
    /* read support mesh  */
    /* TODO : Ceci est optionnel dans ce usescase */ 
    if (strcmp(supportmeshname,"")) {
      if ( MEDsupportMeshInfoByName(fid, supportmeshname, &spacedim, &meshdim, description,
                                    &axistype, axisname, axisunit) < 0 ) {
        MESSAGE("ERROR : read information about mesh support ...");
        goto ERROR;
      }

      ISCRUTE(nnode);
      /* read how many nodes in the support mesh */
      /* Ceci est optionnel dans ce usescase */ 
      if ((nnode = MEDmeshnEntity(fid, supportmeshname, MED_NO_DT, MED_NO_IT, MED_NODE, MED_NONE,
                                  MED_COORDINATE, MED_NO_CMODE,&coordinatechangement,
                                  &geotransformation)) < 0) {
        MESSAGE("ERROR : read number of nodes ...");
        goto ERROR;
      }
     ISCRUTE(nnode);

      /* read support mesh nodes coordinates */
      /* Ceci est optionnel dans ce usescase */ 
      coordinates = (med_float*) malloc(sizeof(med_float)*nnode*spacedim);

      if (MEDmeshNodeCoordinateRd(fid, supportmeshname, MED_NO_DT, MED_NO_IT, MED_FULL_INTERLACE,
                                  coordinates) < 0) {
        MESSAGE("ERROR : read nodes coordinates ...");
        free(coordinates);
        goto ERROR;
      }

      /* free memory */
      free(coordinates);

      /* read how many MED_SEG2 cells in the support mesh */
      /* Ceci est optionnel dans ce usescase */ 
      if ((nseg2 = MEDmeshnEntity(fid, supportmeshname, MED_NO_DT, MED_NO_IT, MED_CELL,geocelltype,
                                  MED_CONNECTIVITY, MED_NODAL, &coordinatechangement,
                                  &geotransformation)) < 0) {
        MESSAGE("ERROR : number of MED_SEG2 ...");
        goto ERROR;
      }
     ISCRUTE(nseg2);
     ISCRUTE(ncell);
      /* read MED_SEG2 connectivity in the support mesh */
      if (nseg2 > 0) {
        seg2connectivity = (med_int *) malloc(sizeof(med_int)*nseg2*2);

        if (MEDmeshElementConnectivityRd(fid, supportmeshname, MED_NO_DT, MED_NO_IT, MED_CELL,
                                         geocelltype, MED_NODAL, MED_FULL_INTERLACE, seg2connectivity) < 0) {
          MESSAGE("ERROR : MED_SEG2 connectivity ...");
          free(seg2connectivity);
          goto ERROR;
        }
        free(seg2connectivity);
      }
    }

    /* read constant attribute(s) */
    /* Optionnel pour ce usescase (cf. usescase lecture modèle) */
    for (j=0; j<nconstatt; j++) {
      if ( MEDstructElementConstAttInfo(fid, elementname, j+1,
                                        attname, &atttype, &nattcomp, &attentitype,
                                        profilename, &profilesize) < 0) {
        MESSAGE("ERROR : const attribute information ...");
        goto ERROR;
      }

      /* if there is a profile => read the profile, see UsesCase_MEDprofile_2 */

      /* memory allocation */
      if (profilesize != 0)
        size = profilesize*nattcomp*MEDstructElementAttSizeof(atttype);
      else
        if (attentitype== MED_NODE)
          size = nnode*nattcomp*MEDstructElementAttSizeof(atttype);
        else
          size = ncell*nattcomp*MEDstructElementAttSizeof(atttype);
      if ( atttype == MED_ATT_NAME) ++size;
      ISCRUTE(size);
      value = (med_float *) malloc(size);


      /* read attribute(s) value(s) */
      if ( MEDstructElementConstAttRd(fid, elementname, attname, (unsigned char *)value ) < 0 ) {
        MESSAGE("ERROR : const attribute value ...");
        free(value);
        goto ERROR;
      }

      /* memory deallocation */
      free(value);
    }

    /* read variable attribute(s) */
    for (j=0; j<*(nvaratt+i); j++) {

      /* read informations about the attribute */
      if ( MEDstructElementVarAttInfo(fid, elementname, j+1, 
                                      attname, &atttype, &nattcomp) < 0) {
            MESSAGE("ERROR : var attribute information ...");
            goto ERROR;
      }
      
      /* memory allocation */
      size = nentities*nattcomp*MEDstructElementAttSizeof(atttype);
      if ( atttype == MED_ATT_NAME) ++size;
      ISCRUTE(size);
      value = (med_float *) malloc((size)*sizeof(char));
      
      /* read attribute values */
      if (MEDmeshStructElementVarAttRd(fid, computmeshname, MED_NO_DT, MED_NO_IT,
                                       *(geotype+i), attname, value ) < 0) {
        MESSAGE("ERROR : read variable attributes values ...");
        free(value);
        goto ERROR;
      }

      /* free memory */
      free(value);
      
    }
    
  }

  ret=0;
 ERROR:

  /* free memory */
  free(geotype);
  free(nvaratt);

  /* close file */
  if (MEDfileClose(fid) < 0) {
    MESSAGE("ERROR : file closing ...");
    ret=-1;
  }

  return ret;
}

Ecriture et lecture en parallèle par la décomposition de domaine

En vue de calculs parallèles, le domaine de calcul est subdivisé en sous-domaines où se répartissent les maillages. Classiquement, chaque sous-domaine sera traité par un seul processeur qui aura uniquement accès aux données des autres sous-domaines par l'intermédiaire de messages.

sous-domaines.png


Du point de vue du stockage, un maillage distribué a la même structure qu'un maillage MED classique mais ses composantes (entités géométrique, familles, groupes) peuvent être réparties sur plusieurs sous-domaines affectés à des processeurs disjoints. Lors de cette distribution certains sommets, faces, arêtes ou mailles se retrouvent sur la frontière commune de deux sous-domaines. L'ensemble de ces éléments communs à deux sous-domaines constitue un joint. Dans un cadre très général, les éléments communs à deux sous-domaines peuvent apparaître comme : la jointure de deux maillages qui se correspondent parfaitement (on parle alors de raccordement conforme), la jointure de deux maillages de pavage différent (raccordement non conforme), le recouvrement de deux maillages qu'il soit conforme ou non.

La notion de joint est assez générale pour permettre de stocker ces trois types d'interface. Elle consiste à donner la liste des couples des numéros correspondant des entités en regard vues du domaine local et vues du domaine distant.


description-joint.png


Un maillage distribué est donc entièrement déterminé par la donnée des maillages affectés à chacun des sous-domaines, par la définition de joints - raccord entre les maillages de sous-domaines voisins, par une numérotation globale optionnelle des entités.

Comme les maillages sont distribués, les données MED s'y rattachant peuvent être stockées dans plusieurs fichiers. La liste de ces fichiers est rassemblée dans un fichier maître au format ASCII. Ce fichier permet de repérer où se trouvent stockées les parties de maillages distribuées correspondant à chaque sous-domaine. Il contient : un entête d'identification ; le nombre de sous-domaines sur lesquels sont distribués les maillages ; les informations nécessaires pour repérer les parties de maillages affectées à chaque sous-domaine. Pour ce faire, il y a autant de lignes que de parties de maillages distribués. Chaque ligne se compose : du nom de maillage global, du numéro de sous-domaine concerné, du nom de maillage local correspondant au maillage global sur ce sous-domaine, du nom de la machine hébergeant le fichier MED contenant ces informations (ce nom peut éventuellement être une adresse IP de la machine et ne comportera pas de blanc), du chemin absolu ou relatif menant à ce fichier

Le fichier ASCII sera au format unix, et le retour à la ligne est un caractère ASCII 10 (caractère Carriage Return seul sans caractère Line Feed comme sous windows). Dans les chemins, les sous répertoires seront délimités par le caractère '/'. Toute ligne commençant par '#' sera ignorée par la librairie (commentaires). Mais un '#' en cours de ligne ne sera pas interprété comme un commentaire.

Les fichiers MED correspondant à chaque sous-domaine sont repérés par leur chemin absolu ou relatif dans le système de fichier. Dans le cas relatif, l'accès aux fichiers depuis la librairie pourra dépendre de la machine ou du système d'exploitation sur lequel on s'exécute. A charge de l'utilisateur de vérifier l'interprétation cohérente des chemins de fichiers relatifs.


temp-vitesse.png




Voici un exemple de fichier maître, décrivant la répartition de 2 maillages VIT et TEMP sur 4 sous domaines disjoints. Le calcul s'effectue sur un solide (où seule est définie la température) baignée d'un liquide (ou sont définies les vitesses et températures)

# MED Fichier v3.0
#
# Nombre de sous-domaines
4
#
# fichiers MED par sous-domaine
VIT 1 VIT_1 localhost /absolute/path/fichier_dom_1
VIT 2 VIT_2 localhost /absolute/path/fichier_dom_2
TEMP 1 TEMP_1 localhost /absolute/path/fichier_dom_1
TEMP 2 TEMP_2 localhost /absolute/path/fichier_dom_2
TEMP 3 TEMP_3 localhost /absolute/path/fichier_dom_3
TEMP 4 TEMP_4 localhost /absolute/path/fichier_dom_4

La création ou la transformation du fichier maître est à la charge du découpeur. On suppose que ce fichier est cohérent dans l'utilisation de la librairie.

A l'écriture, les routines disponibles permettent de : créer un joint dans un maillage (MEDsubdomainJointCr / msdjcr) ; écrire un tableau de correspondances entre binômes d'entités du maillage dans un joint (MEDsubdomainCorrespondenceWr / msdcrw) ; écrire la numérotation globale associée à un type d'entité pour la repérer sur le domaine global (MEDmeshGlobalNumberWr / mmhgnw).


A la lecture, les routines disponibles permettent de : lire le nombre de joints dans un maillage (MEDnSubdomainJoint / msdnjn) ; lire les informations concernant un joint (MEDsubdomainJointInfo / msdjni), lire le nombre de couple en correspondance d'un type donné dans un joint (MEDsubdomainComputingStepInfo / msdcsi) ; lire le nombre d'entités en correspondance dans un joint pour un couple d'entités et une séquence de calcul donnés (MEDsubdomainCorrespondenceSize / msdcsz); lire les informations sur les couples d'entités en correspondance dans un joint pour une séquence de calcul donnée (MEDsubdomainCorrespondenceSizeInfo / msdszi) ; lire un tableau de correspondances entre binômes d'entités du maillage dans un joint (MEDsubdomainCorrespondenceRd / msdcrr) ; lire la numérotation globale associée à un type d'entité pour la repérer sur le domaine global (MEDmeshGlobalNumberRd / mmhgnr).

Les cas d'utilisation suivant illustrent comment écrire et lire des maillages avec des joints et un système de numérotation global.

/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */

/******************************************************************************
 * - Nom du fichier : test29.c
 *
 * - Description : ecriture d'un joint dans un maillage MED 
 *
 *****************************************************************************/

#include <med.h>
#define MESGERR 1
#include <med_utils.h>

#ifdef DEF_LECT_ECR
#define MODE_ACCES MED_ACC_RDWR
#elif DEF_LECT_AJOUT
#define MODE_ACCES MED_ACC_RDEXT
#else
#define MODE_ACCES MED_ACC_CREAT
#endif

int main (int argc, char **argv)


{
  med_idt fid;

  char maa[MED_NAME_SIZE+1]= "maa1";
  char jnt[MED_NAME_SIZE+1] = "joint";
  char des_jnt[MED_COMMENT_SIZE+1] = "joint avec le sous-domaine 2";
  char maa_distant[MED_NAME_SIZE+1]= "maa1";
  med_int dom_dist = 2;

  med_int mdim = 3;
  med_int ncor = 3;
  med_int cor[6] = {1,2,3,4,5,6};
  med_int cor2[6] = {10,20,30,40,50,60};
  char nomcoo[3*MED_SNAME_SIZE+1] = "x               y               z               ";
  char unicoo[3*MED_SNAME_SIZE+1] = "cm              cm              cm              ";


  /* Creation du fichier "test29.med" */
  if ((fid = MEDfileOpen("test29.med",MODE_ACCES)) < 0) {
    MESSAGE("Erreur a la creation du fichier test29.med");
    return -1;
  }

  if (MEDmeshCr( fid, maa, mdim, mdim, MED_UNSTRUCTURED_MESH,
                 "un maillage pour test29","s", MED_SORT_DTIT,
                 MED_CARTESIAN, nomcoo, unicoo) < 0) {
    MESSAGE("Erreur a la creation du maillage : "); SSCRUTE(maa);
    return -1;
  }

  /* Creation du joint */
  if (MEDsubdomainJointCr(fid,maa,jnt,des_jnt,dom_dist,maa_distant) < 0) {
    MESSAGE("Erreur a la creation du joint");
    return -1;
  }

  /* Ecriture de la correspondance Noeud, Noeud */
  if (MEDsubdomainCorrespondenceWr(fid,maa,jnt,MED_NO_DT,MED_NO_IT,
                                   MED_NODE,MED_NONE,MED_NODE,MED_NONE,ncor,cor) < 0) {
    MESSAGE("Erreur a l'ecriture du tableau des correspondances (noeud,noeud)");
    return -1;
  }

  /* Ecriture de la correspondance Noeud Maille */
  if (MEDsubdomainCorrespondenceWr(fid,maa,jnt,MED_NO_DT,MED_NO_IT,
                                   MED_NODE,MED_NONE,MED_CELL,MED_TRIA3,ncor,cor2) < 0) {
    MESSAGE("Erreur a l'ecriture du tableau des correspondances (noeud,maille TRIA3)");
    return -1;
  }

  /* Fermeture du fichier */
  if (MEDfileClose(fid) < 0) {
    MESSAGE("Erreur a la fermeture du fichier");
    return -1;
  }

  return 0;
}




/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */

/******************************************************************************
 * - Nom du fichier : test30.c
 *
 * - Description : lecture des joints d'un maillage MED.
 *
 *****************************************************************************/

#include <med.h>
#define MESGERR 1
#include <med_utils.h>

#ifdef DEF_LECT_ECR
#define MODE_ACCES MED_ACC_RDWR
#elif DEF_LECT_AJOUT
#define MODE_ACCES MED_ACC_RDEXT
#else
#define MODE_ACCES MED_ACC_CREAT
#endif

int afficheCorres(med_idt fid, char *maa, char *jnt,
                 med_entity_type typ_ent_local,   med_geometry_type typ_geo_local,
                 med_entity_type typ_ent_distant, med_geometry_type typ_geo_distant,
                 char *type);

int main (int argc, char **argv)


{
  med_err ret = 0;
  med_idt fid;
  char maa[MED_NAME_SIZE+1],maa_dist[MED_NAME_SIZE+1];
  med_int mdim,sdim;
  med_int njnt,ncor,ndom,nc;
  char jnt[MED_NAME_SIZE+1],corr[MED_NAME_SIZE+1];
  char des[MED_COMMENT_SIZE+1];
  char dtunit[MED_SNAME_SIZE+1]="";
  char nomcoo[3*MED_SNAME_SIZE+1];
  char unicoo[3*MED_SNAME_SIZE+1];
  med_axis_type rep;
  med_mesh_type type;
  med_sorting_type sort;
  med_int nstep=0,njstep=0,nodtitncor=0,nentity=0;
  med_entity_type typ_ent_local,typ_ent_distant;
  med_geometry_type typ_geo_local,typ_geo_distant;
  int i,j,k;

  if (argc != 2) {
    MESSAGE("Il faut passer un fichier MED en paramètre");
    return -1;
  }

  /* Ouverture du fichier passe en argument en lecture seule */
  if ((fid = MEDfileOpen(argv[1],MED_ACC_RDONLY)) < 0) {
    MESSAGE("Erreur à l'ouverture du fichier : "); SSCRUTE(argv[1]);
    return -1;
  }

  if ((sdim=MEDmeshnAxis(fid, 1)) <0) {
    MESSAGE("Erreur à la lecture de la dimension de l'espace du maillage :");
    SSCRUTE(maa);
    return -1;
  }

  /* Lecture des infos concernant le premier maillage */
  if ( MEDmeshInfo( fid, 1,  maa, &sdim, &mdim, &type, des, dtunit, &sort,
                    &nstep,  &rep, nomcoo,unicoo) < 0 ) {
    MESSAGE("Erreur a la lecture des informations sur le maillage : ");SSCRUTE(maa);
    return -1;
  } else {
    printf("Maillage de nom : |%s| , de dimension : "IFORMAT" , et de type %d\n",maa,mdim,type);
    printf("\t -Dimension de l'espace : "IFORMAT"\n",sdim);
    printf("\t -Description du maillage : |%s|\n",des);
    printf("\t -Noms des axes : |%s|\n",nomcoo);
    printf("\t -Unités des axes : |%s|\n",unicoo);
    printf("\t -Type de repère : %d\n",rep);
    printf("\t -Nombre d'étapes de calcul : "IFORMAT"\n",nstep);
    printf("\t -Unité des dates : |%s|\n\n",dtunit);
  }

  /* Lecture du nombre de joints */
  if ((njnt = MEDnSubdomainJoint(fid,maa)) < 0) {
    MESSAGE("Erreur a la lecture du nombre de joints");
    return -1;
  }
  printf("Nombre de joints : "IFORMAT" \n",njnt);

  /* Lecture de tous les joints du maillage */
  for (i = 0;i<njnt;i++) {
    printf("Joint numero : %d \n",i+1);

    /* Lecture des infos sur le joints */
    if (MEDsubdomainJointInfo(fid,maa,i+1,jnt,des,&ndom,maa_dist,&njstep,&nodtitncor) < 0) {
      MESSAGE("Erreur a la lecture du joint d'indice");
      ISCRUTE_int(i+1);
      return -1;
    }
    printf("Nom du joint: |%s| \n",jnt);
    printf("Description du joint      : |%s| \n",des);
    printf("Domaine en regard         : "IFORMAT" \n",ndom);
    printf("Maillage distant          : |%s| \n",maa_dist);
    printf("Nombre d'étapes de calcul : "IFORMAT" \n",njstep);
    printf("Nombre de correspondance pour (NO_DT,NO_IT) : "IFORMAT" \n",nodtitncor);



    /* lecture des correspondances une par une
       en connaissant leur type a priori */

    /* Lecture de la correspondance Noeud Noeud */
    afficheCorres(fid,maa,jnt,MED_NODE,0,MED_NODE,0,"noeud/noeud");

    /* Lecture de la correspondance Noeud Maille */
    afficheCorres(fid,maa,jnt,MED_NODE,0,MED_CELL,MED_TRIA3,"noeud/TRIA3");


    /* lecture des correspondances une par une
       sans connaitre leur type a priori
       -> utilisation de la fonction MEDjointTypeCorres */

    ncor=1;

    while ( ncor <= nodtitncor ) {
      ISCRUTE(ncor);
      if ( MEDsubdomainCorrespondenceSizeInfo(fid,maa,jnt,MED_NO_DT,MED_NO_IT,ncor,
                                           &typ_ent_local,&typ_geo_local,&typ_ent_distant,&typ_geo_distant,
                                              &nentity) < 0 ) {
        MESSAGE("Erreur a la lecture des infos sur le nombre d'entite en regard");
        return -1;
      }

      /* Lecture de la correspondance Noeud Noeud */
      afficheCorres(fid,maa,jnt,typ_ent_local,typ_geo_local,typ_ent_distant,typ_geo_distant,"------");

      ncor++;
    }

  }

  /* Fermeture du fichier */
  if (MEDfileClose(fid) < 0) {
    MESSAGE("Erreur a la fermeture du fichier ");
    return -1;
  }

  return ret;
}




int afficheCorres(med_idt fid, char *maa, char *jnt,
                 med_entity_type typ_ent_local,   med_geometry_type typ_geo_local,
                 med_entity_type typ_ent_distant, med_geometry_type typ_geo_distant,
                 char *type)
{
  med_int nc;
  med_int *cortab;
  int k,ncor,ret=0;

  ISCRUTE_int(typ_ent_local);ISCRUTE_int(typ_geo_local);
  ISCRUTE_int(typ_ent_distant);ISCRUTE_int(typ_geo_distant);
  if ( MEDsubdomainCorrespondenceSize(fid,maa,jnt,MED_NO_DT,MED_NO_IT,
                                      typ_ent_local,typ_geo_local,typ_ent_distant,typ_geo_distant,
                                      &nc) < 0) {
    MESSAGE("Erreur a la lecture des infos sur le nombre d'entite en regard de type");
    SSCRUTE(type);
    return -1;
  }

  printf("nb de couples d'entites en regard |%s|: "IFORMAT" \n",type,nc);

  if (nc > 0) {
    cortab = (med_int*) malloc(sizeof(med_int)*nc*2);
    if ((ret=MEDsubdomainCorrespondenceRd(fid,maa,jnt,MED_NO_DT,MED_NO_IT,
                                          typ_ent_local,typ_geo_local,typ_ent_distant,typ_geo_distant,
                                          cortab)) < 0) {
      MESSAGE("Erreur a la lecture des correspondances sur ");
      SSCRUTE(type);
      ret = -1;
    }
    if (ret == 0)
      for (k=0;k<nc;k++)
        printf("Correspondance %d : "IFORMAT" et "IFORMAT" \n",k+1,*(cortab+2*k),
               *(cortab+2*k+1));
    free(cortab);
  }
  return ret;
}

/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */

/******************************************************************************
 * - Nom du fichier : test31.c
 *
 * - Description : ecriture d'une numerotation globale dans un maillage MED 
 *
 *****************************************************************************/

#include <med.h>
#define MESGERR 1
#include <med_utils.h>


#ifdef DEF_LECT_ECR
#define MODE_ACCES MED_ACC_RDWR
#elif DEF_LECT_AJOUT
#define MODE_ACCES MED_ACC_RDEXT
#else
#define MODE_ACCES MED_ACC_CREAT
#endif

int main (int argc, char **argv)


{
  med_err ret = 0;
  med_idt fid;
  med_int mdim,sdim;
  /* nom du maillage de longueur maxi MED_NAME_SIZE */
  char maa[MED_NAME_SIZE+1];
  /* le nombre de noeuds */
  med_int nnoe = 0;
  /* table des numeros global */
  med_int *numglobalnoe=NULL;

  /* variable de stockage pour reperer le maillage */
  med_int i;
  char des[MED_COMMENT_SIZE+1]="";
  char dtunit[MED_SNAME_SIZE+1]="";
  char nomcoo[3*MED_SNAME_SIZE+1]="";
  char unicoo[3*MED_SNAME_SIZE+1]="";
  med_axis_type rep;
  med_mesh_type type;
  med_sorting_type sort;
  med_int nstep=0;
  med_bool chgt=MED_FALSE,trsf=MED_FALSE;



  if (argc != 2) {
    MESSAGE("Il faut passer un fichier MED en param�tre");
    return -1;
  }

  /* Ouverture du fichier passe en argument */
  if ((fid = MEDfileOpen(argv[1],MED_ACC_RDWR)) < 0) {
    MESSAGE("Erreur a l'ouverture du fichier : "); SSCRUTE(argv[1]);
    return -1;
  }
  

  if ((sdim=MEDmeshnAxis(fid, 1)) <0) {
    MESSAGE("Erreur � la lecture de la dimension de l'espace du maillage :");
    SSCRUTE(maa);
    return -1;
  }

  /* Lecture des infos concernant le premier maillage */
  if ( MEDmeshInfo( fid, 1,  maa, &sdim, &mdim, &type, des, dtunit, &sort,
                    &nstep,  &rep, nomcoo,unicoo) < 0 ) {
    MESSAGE("Erreur a la lecture des informations sur le maillage : ");SSCRUTE(maa);
    return -1;
  } else {
    printf("Maillage de nom : |%s| , de dimension : "IFORMAT" , et de type %d\n",maa,mdim,type);
    printf("\t -Dimension de l'espace : "IFORMAT"\n",sdim);
    printf("\t -Description du maillage : %s\n",des);
    printf("\t -Noms des axes : %s\n",nomcoo);
    printf("\t -Unit�s des axes : %s\n",unicoo);
    printf("\t -Type de rep�re : %d\n",rep);
    printf("\t -Nombre d'�tapes de calcul : "IFORMAT"\n",nstep);
    printf("\t -Unit� des dates : %s\n\n",dtunit);
  }

  /* Lecture du nombre de noeuds */
  if ( (nnoe = MEDmeshnEntity(fid,maa,MED_NO_DT,MED_NO_IT,
                              MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,
                              &chgt,&trsf)) < 0) {
    MESSAGE("Erreur a la lecture du nombre de noeuds ");
    return -1;
  }
  printf("Nombre de noeuds : "IFORMAT" \n",nnoe);

  /* Allocations memoires */

  /* table de la numerotation globale
     profil : (nombre de noeuds ) */
  if (nnoe > 0) {
    numglobalnoe = (med_int*) malloc(sizeof(med_int)*nnoe);
    for (i=0;i<nnoe;i++) {
      numglobalnoe[i]=i+100;
    }
  }

  /* ecriture de la numerotation globale */

  if (MEDmeshGlobalNumberWr(fid,maa,MED_NO_DT,MED_NO_IT,MED_NODE,MED_NONE,nnoe,numglobalnoe)<0) {
    MESSAGE("Erreur a l''ecriture de la numerotation globale");
    return -1;
  }

  free(numglobalnoe);

  /* Fermeture du fichier */
  if (MEDfileClose(fid) < 0) {
    MESSAGE("Erreur a la fermeture du fichier");
    return -1;
  }

  return 0;
}




/*  This file is part of MED.
 *
 *  COPYRIGHT (C) 1999 - 2015  EDF R&D, CEA/DEN
 *  MED is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MED 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
 */

/******************************************************************************
 * - Nom du fichier : test32.c
 *
 * - Description : lecture nominale d'une numerotation globale dans un maillage MED 
 *
 *****************************************************************************/

#include <med.h>
#define MESGERR 1
#include <med_utils.h>

#ifdef DEF_LECT_ECR
#define MODE_ACCES MED_ACC_RDWR
#elif DEF_LECT_AJOUT
#define MODE_ACCES MED_ACC_RDEXT
#else
#define MODE_ACCES MED_ACC_CREAT
#endif

int main (int argc, char **argv)


{
  med_err ret = 0;
  med_idt fid;
  med_int mdim,sdim;
  char maa[MED_NAME_SIZE+1];
  /* le nombre de noeuds */
  med_int nnoe = 0;
  /* table des numeros global */
  med_int *numglobalnoe=NULL;
  /* variable de stockage pour reperer le maillage */
  med_int i;
  char des[MED_COMMENT_SIZE+1]="";
  char dtunit[MED_SNAME_SIZE+1]="";
  char nomcoo[3*MED_SNAME_SIZE+1]="";
  char unicoo[3*MED_SNAME_SIZE+1]="";
  med_axis_type rep;
  med_mesh_type type;
  med_sorting_type sort;
  med_int nstep=0;
  med_bool chgt=MED_FALSE,trsf=MED_FALSE;



  if (argc != 2) {
    MESSAGE("Il faut passer un fichier MED en param�tre");
    return -1;
  }

  /* Ouverture du fichier passe en argument */
  if ((fid = MEDfileOpen(argv[1],MED_ACC_RDWR)) < 0) {
    MESSAGE("Erreur a l'ouverture du fichier : "); SSCRUTE(argv[1]);
    return -1;
  }

  if ((sdim=MEDmeshnAxis(fid, 1)) <0) {
    MESSAGE("Erreur � la lecture de la dimension de l'espace du maillage :");
    SSCRUTE(maa);
    return -1;
  }

  /* Lecture des infos concernant le premier maillage */
  if ( MEDmeshInfo( fid, 1,  maa, &sdim, &mdim, &type, des, dtunit, &sort,
                    &nstep,  &rep, nomcoo,unicoo) < 0 ) {
    MESSAGE("Erreur a la lecture des informations sur le maillage : ");SSCRUTE(maa);
    return -1;
  } else {
    printf("Maillage de nom : |%s| , de dimension : "IFORMAT" , et de type %d\n",maa,mdim,type);
    printf("\t -Dimension de l'espace : "IFORMAT"\n",sdim);
    printf("\t -Description du maillage : %s\n",des);
    printf("\t -Noms des axes : %s\n",nomcoo);
    printf("\t -Unit�s des axes : %s\n",unicoo);
    printf("\t -Type de rep�re : %d\n",rep);
    printf("\t -Nombre d'�tapes de calcul : "IFORMAT"\n",nstep);
    printf("\t -Unit� des dates : %s\n\n",dtunit);
  }

  /* Lecture du nombre de noeuds */
  if ( (nnoe = MEDmeshnEntity(fid,maa,MED_NO_DT,MED_NO_IT,
                              MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,
                              &chgt,&trsf)) < 0) {
    MESSAGE("Erreur a la lecture du nombre de noeuds ");
    return -1;
  }
  printf("Nombre de noeuds : "IFORMAT" \n",nnoe);


  /* Allocations memoires */

  /* table de la numerotation globale
     profil : (nombre de noeuds ) */
  if (nnoe > 0) {
    numglobalnoe = (med_int*) malloc(sizeof(med_int)*nnoe);
  }

  /* lecture de la numerotation globale attachee aux noeuds*/
  if (MEDmeshGlobalNumberRd(fid,maa,MED_NO_DT,MED_NO_IT,MED_NODE,MED_NONE,numglobalnoe)<0) {
    MESSAGE("Erreur a la lecture de de la numerotation globale");
    return -1;
  }

  /* ecriture a l'ecran des resultats */
  for (i=0;i<nnoe;i++)
    printf("Numero global du noeud "IFORMAT" : "IFORMAT" \n",i+1,numglobalnoe[i]);

  free(numglobalnoe);

  /* Fermeture du fichier */
  if (MEDfileClose(fid) < 0) {
    MESSAGE("Erreur a la fermeture du fichier ");
    return -1;
  }

  return 0;
}




Généré le Thu Oct 8 14:27:14 2015 pour MED fichier par  doxygen 1.6.1