1 /*============================================================================
2  *  Définition de la fonction
3  *   de lecture d'un fichier de maillage au format MED
4  *============================================================================*/
5 
6 /*
7   This file is part of Code_Saturne, a general-purpose CFD tool.
8 
9   Copyright (C) 1998-2021 EDF S.A.
10 
11   This program is free software; you can redistribute it and/or modify it under
12   the terms of the GNU General Public License as published by the Free Software
13   Foundation; either version 2 of the License, or (at your option) any later
14   version.
15 
16   This program is distributed in the hope that it will be useful, but WITHOUT
17   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
19   details.
20 
21   You should have received a copy of the GNU General Public License along with
22   this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
23   Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 */
25 
26 /*----------------------------------------------------------------------------*/
27 
28 
29 /*============================================================================
30  *                                 Visibilité
31  *============================================================================*/
32 
33 #include "cs_config.h"
34 
35 #if defined(HAVE_MED)
36 
37 
38 /*----------------------------------------------------------------------------
39  *  Fichiers `include' librairie standard C
40  *----------------------------------------------------------------------------*/
41 
42 #include <assert.h>
43 #include <ctype.h>
44 #include <stdlib.h>
45 #include <string.h>
46 
47 
48 /*----------------------------------------------------------------------------
49  *  Fichiers `include' visibles du  paquetage global "Utilitaire"
50  *----------------------------------------------------------------------------*/
51 
52 #include "ecs_def.h"
53 #include "ecs_elt_typ_liste.h"
54 #include "ecs_mem.h"
55 
56 
57 /*----------------------------------------------------------------------------
58  *  Fichiers `include' visibles des paquetages visibles
59  *----------------------------------------------------------------------------*/
60 
61 #include "ecs_descr.h"
62 #include "ecs_descr_chaine.h"
63 #include "ecs_famille.h"
64 #include "ecs_famille_chaine.h"
65 #include "ecs_maillage.h"
66 #include "ecs_maillage_priv.h"
67 
68 
69 /*----------------------------------------------------------------------------
70  *  Fichiers `include' visibles du  paquetage courant
71  *----------------------------------------------------------------------------*/
72 
73 #include "ecs_maillage_pre.h"
74 
75 
76 /*----------------------------------------------------------------------------
77  *  Fichier  `include' du  paquetage courant associe au fichier courant
78  *----------------------------------------------------------------------------*/
79 
80 #include "ecs_pre_med.h"
81 
82 
83 /*----------------------------------------------------------------------------
84  *  Fichiers `include' prives   du  paquetage courant
85  *----------------------------------------------------------------------------*/
86 
87 #include "ecs_med_priv.h"
88 
89 
90 /*============================================================================
91  *                              Fonctions privees
92  *============================================================================*/
93 
94 /*----------------------------------------------------------------------------
95  *  Création d'une structure `ecs_med_t' et ouverture d'un fichier MED
96  *  en lecture
97  *----------------------------------------------------------------------------*/
98 
99 static ecs_med_t *
ecs_pre_med__cree(const char * nom_fichier)100 ecs_pre_med__cree(const char  *nom_fichier)
101 {
102   ecs_med_t  * fic;
103 
104   med_err retval = 0;
105 
106   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
107 
108   ECS_MALLOC(fic, 1, ecs_med_t);
109 
110   ECS_MALLOC(fic->nom_fic, strlen(nom_fichier) + 1, char);
111   strcpy(fic->nom_fic, nom_fichier);
112 
113   fic->fid = MEDfileOpen(fic->nom_fic, MED_ACC_RDONLY);
114 
115   if (fic->fid < 0)
116     ecs_error(__FILE__, __LINE__, 0,
117               _("MED: error opening file \"%s\"."), nom_fichier);
118 
119   retval = MEDfileNumVersionRd(fic->fid,
120                                &(fic->version[0]),
121                                &(fic->version[1]),
122                                &(fic->version[2]));
123 
124   if (retval < 0)
125     ecs_error(__FILE__, __LINE__, 0,
126               _("MED: error checking file version \"%s\"."), nom_fichier);
127 
128   fic->nbr_maillages = 0;
129   fic->tab_maillages = NULL;
130 
131   return fic;
132 }
133 
134 /*----------------------------------------------------------------------------
135  *  Fermeture d'un fichier MED en lecture et destruction de la structure
136  *  `ecs_med_t' associée
137  *----------------------------------------------------------------------------*/
138 
139 static ecs_med_t *
ecs_pre_med__detruit(ecs_med_t * fic)140 ecs_pre_med__detruit(ecs_med_t  * fic)
141 {
142   med_err retval = 0;
143 
144   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
145 
146   assert(fic != NULL);
147 
148   retval = MEDfileClose(fic->fid);
149 
150   if (retval != 0)
151     ecs_error(__FILE__, __LINE__, 0,
152               _("MED: error closing file \"%s\"."),
153               fic->nom_fic);
154 
155   ECS_FREE(fic->nom_fic);
156   ECS_FREE(fic);
157 
158   return fic;
159 }
160 
161 /*----------------------------------------------------------------------------
162  *  Fonction qui renvoie un pointeur sur un tableau de type `ecs_int_t'
163  *   dont les valeurs sont converties si nécessaire
164  *   à partir du tableau de connectivité `val_med' ayant `nbr_val' valeurs
165  *   de type `med_int', avec `pas_med' valeurs MED et `pas_ecs' valeurs
166  *   locales par élement.
167  *
168  *  Cette fonction supprime donc les références inutiles (noeuds
169  *   quadratiques ou connectivités supplémentaires éventuelles)
170  *
171  *  Le tableau en entrée `val_med' est libéré si le tableau renvoyé est alloué
172  *----------------------------------------------------------------------------*/
173 
174 static ecs_int_t *
ecs_loc_convert_connect_med_ecs(med_int * val_med,const ecs_int_t nbr_val,const ecs_int_t pas_med,const ecs_int_t pas_ecs)175 ecs_loc_convert_connect_med_ecs(med_int          *val_med,
176                                 const ecs_int_t   nbr_val,
177                                 const ecs_int_t   pas_med,
178                                 const ecs_int_t   pas_ecs)
179 {
180   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
181 
182   assert(val_med != NULL);
183   assert(nbr_val != 0);
184   assert(pas_med != 0);
185   assert(pas_ecs != 0);
186 
187   if ((pas_med == pas_ecs) && (sizeof(med_int) == sizeof(ecs_int_t))) {
188 
189     /* Le nombre de références par élément    */
190     /* MED est le même que celui par élément  */
191     /* local (élément linéaire, pas de        */
192     /* connectivité supplémentaire)           */
193 
194     /* Les entiers de type `med_int' et       */
195     /* les entiers de type `ecs_int_t'        */
196     /* sont codés sur le meme nombre d'octets */
197 
198     /* Aucune conversion n'est nécessaire     */
199 
200     return (ecs_int_t *)val_med;
201 
202   }
203   else {
204 
205     ecs_int_t    ielt;
206     ecs_int_t    iloc;
207     ecs_int_t    ipos_ecs;
208     ecs_int_t    ipos_med;
209     ecs_int_t    nbr_val_ecs;
210     ecs_int_t  * val_ecs;
211 
212     /* Les entiers de type `med_int' et `ecs_int_t'  */
213     /* ne sont pas codés sur le même nombre d'octets */
214 
215     /* On effectue la conversion de type pour chaque valeur */
216 
217     nbr_val_ecs = (nbr_val / pas_med) * pas_ecs;
218 
219     ECS_MALLOC(val_ecs, nbr_val_ecs, ecs_int_t);
220 
221     ipos_ecs = 0;
222 
223     for (ielt = 0; ielt < (nbr_val / pas_med); ielt++) {
224 
225       ipos_med = ielt * pas_med;
226 
227       for (iloc = 0; iloc < pas_ecs; iloc++)
228         val_ecs[ipos_ecs++] = (ecs_int_t)val_med[ipos_med++];
229 
230     }
231 
232     ECS_FREE(val_med);
233 
234     return val_ecs;
235   }
236 }
237 
238 /*----------------------------------------------------------------------------
239  *  Fonction qui renvoie un pointeur sur un tableau de type `double'
240  *   dont les valeurs sont converties si nécessaire
241  *   à partir du tableau `val_med' ayant `nbr_val' valeurs de type `med_float'
242  *
243  *  Le tableau en entrée `val_med' est libere si le tableau renvoyé est alloué
244  *----------------------------------------------------------------------------*/
245 
246 static ecs_coord_t *
ecs_loc_convert_real_med_ecs(med_float * val_med,ecs_int_t nbr_val)247 ecs_loc_convert_real_med_ecs(med_float  *val_med,
248                              ecs_int_t   nbr_val)
249 {
250   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
251 
252   assert(val_med != NULL);
253   assert(nbr_val != 0);
254 
255   if (sizeof(med_float) == sizeof(ecs_coord_t)) {
256 
257     /* Les réels de type `med_float' et `ecs_coord_t' */
258     /* sont codés sur le même nombre d'octets */
259 
260     /* Aucune conversion n'est nécessaire */
261 
262     return (ecs_coord_t *)val_med;
263   }
264   else {
265 
266     ecs_int_t   ival;
267     ecs_coord_t    * val_ecs;
268 
269     /* Les réels de type `med_float' et `ecs_coord_t' */
270     /* ne sont pas codés sur le même nombre d'octets  */
271 
272     /* On effectue la conversion de type pour chaque valeur */
273 
274     ECS_MALLOC(val_ecs, nbr_val, ecs_coord_t);
275 
276     for (ival = 0; ival < nbr_val; ival++)
277       val_ecs[ival] = (ecs_coord_t)val_med[ival];
278 
279     ECS_FREE(val_med);
280 
281     return val_ecs;
282   }
283 }
284 
285 /*----------------------------------------------------------------------------
286  *                        Lecture des noeuds
287  *----------------------------------------------------------------------------*/
288 
289 static void
ecs_loc_pre_med__lit_noeud(ecs_maillage_t * maillage,const ecs_med_t * fic_maillage,const char * nom_maillage,int dim_e)290 ecs_loc_pre_med__lit_noeud(ecs_maillage_t   *maillage,
291                            const ecs_med_t  *fic_maillage,
292                            const char       *nom_maillage,
293                            int               dim_e)
294 {
295   /* Declarations des variables de stockage        */
296   /* avant transfert dans la structure du maillage */
297   /*-----------------------------------------------*/
298 
299   ecs_int_t     nbr_som;
300   ecs_coord_t  *som_val_coord;
301 
302   /* Declarations des variables pour MED */
303   /*-------------------------------------*/
304 
305   med_int      mdim_med;
306 
307   med_int      nbr_noe_med;
308   med_int     *fam_noe_med;
309   med_int     *num_noe_med;
310 
311   med_float   *coord_med;
312 
313   med_err      ret_med = 0;
314 
315   med_bool     changement = MED_FALSE;
316   med_bool     transformation = MED_FALSE;
317 
318   char         nom_maillage_med[MED_NAME_SIZE + 1];
319 
320   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
321 
322   strcpy(nom_maillage_med, nom_maillage);
323 
324   /* On recupere le nombre de noeuds */
325 
326   nbr_noe_med = MEDmeshnEntity(fic_maillage->fid,
327                                nom_maillage_med,
328                                MED_NO_DT,
329                                MED_NO_IT,
330                                MED_NODE,
331                                MED_NONE,
332                                MED_COORDINATE,
333                                MED_NODAL,
334                                &changement,
335                                &transformation);
336 
337   if (nbr_noe_med < 0)
338     ret_med = -1;
339 
340   if (ret_med != 0)
341     ecs_error(__FILE__, __LINE__, 0,
342               _("MED: error reading file \"%s\".\n"
343                 "Number of vertices of entity read: \"%d\"."),
344               fic_maillage->nom_fic, (int)nbr_noe_med);
345 
346   /*------------------------------------*/
347   /* Lecture des coordonnées des noeuds */
348   /*------------------------------------*/
349 
350   mdim_med = (med_int)dim_e;
351 
352   ECS_MALLOC(coord_med,   nbr_noe_med * mdim_med,            med_float);
353   ECS_MALLOC(fam_noe_med, nbr_noe_med,                       med_int);
354   ECS_MALLOC(num_noe_med, nbr_noe_med,                       med_int);
355 
356   ret_med = MEDmeshNodeCoordinateRd(fic_maillage->fid,
357                                     nom_maillage_med,
358                                     MED_NO_DT,
359                                     MED_NO_IT,
360                                     MED_FULL_INTERLACE,
361                                     coord_med);
362 
363   if (ret_med != 0)
364     ecs_error(__FILE__, __LINE__, 0,
365               _("MED: error reading file \"%s\".\n"
366                 "Error reading coordinates."),
367               fic_maillage->nom_fic);
368 
369   ECS_FREE(fam_noe_med);
370   ECS_FREE(num_noe_med);
371 
372   /* Transformation du tableau des coord au type `med_float'   */
373   /*             en un tableau des coord au type `ecs_coord_t' */
374   /*-----------------------------------------------------------*/
375 
376   nbr_som = (ecs_int_t)nbr_noe_med;
377 
378   som_val_coord = ecs_loc_convert_real_med_ecs(coord_med,
379                                                nbr_som * dim_e);
380 
381   if (dim_e != 3) {
382 
383     ecs_int_t isom;
384 
385     ECS_REALLOC(som_val_coord, nbr_som * 3, ecs_coord_t);
386 
387     if (dim_e == 1) {
388 
389       for (isom = nbr_som-1; isom >= 0; isom--) {
390         som_val_coord[isom*3    ] = som_val_coord[isom];
391         som_val_coord[isom*3 + 1] = 0.0;
392         som_val_coord[isom*3 + 2] = 0.0;
393       }
394 
395     }
396     else if (dim_e == 2) {
397 
398       for (isom = nbr_som-1; isom >= 0; isom--) {
399         som_val_coord[isom*3    ] = som_val_coord[isom*2    ];
400         som_val_coord[isom*3 + 1] = som_val_coord[isom*2 + 1];
401         som_val_coord[isom*3 + 2] = 0.0;
402       }
403 
404     }
405   }
406 
407   /* Transfert des valeurs lues dans la structure d'entite de maillage */
408   /*===================================================================*/
409 
410   ecs_maillage_pre__cree_som(maillage,
411                              nbr_som,
412                              som_val_coord);
413 }
414 
415 /*----------------------------------------------------------------------------
416  *                        Lecture des éléments
417  *----------------------------------------------------------------------------*/
418 
419 static void
ecs_loc_pre_med__lit_maille(ecs_maillage_t * maillage,const ecs_med_t * fic_maillage,const char * nom_maillage)420 ecs_loc_pre_med__lit_maille(ecs_maillage_t   *maillage,
421                             const ecs_med_t  *fic_maillage,
422                             const char       *nom_maillage)
423 {
424   ecs_entmail_t   entmail_e;
425 
426   ecs_int_t     cpt_som;
427   ecs_int_t     ient;
428   ecs_int_t     ielt;
429   ecs_int_t     isom;
430   ecs_int_t     ityp;
431   ecs_int_t     nbr_elt;
432   ecs_int_t     nbr_som_elt;
433   ecs_int_t     nbr_som_fac;
434   ecs_int_t     pos_elt;
435   ecs_int_t     renum_som;
436   ecs_int_t     taille;
437   ecs_int_t     typ_geo_ecs;
438 
439   ecs_int_t    *elt_val_som;
440 
441   /* Déclarations des variables de stockage        */
442   /* avant transfert dans la structure du maillage */
443   /*-----------------------------------------------*/
444 
445   size_t      cpt_elt_ent[ECS_N_ENTMAIL];        /* Nbr. elts par entite */
446   ecs_size_t *elt_pos_som_ent[ECS_N_ENTMAIL];    /* Positions sommets    */
447   ecs_int_t  *elt_val_som_ent[ECS_N_ENTMAIL];    /* Numeros des sommets  */
448   int        *elt_val_fam_ent[ECS_N_ENTMAIL];    /* Familles elements    */
449 
450   /* Déclarations des variables pour MED */
451   /*-------------------------------------*/
452 
453   char               nom_maillage_med[MED_NAME_SIZE + 1] = "";
454   char               nom_equiv[MED_NAME_SIZE+1] = "";
455 
456   med_geometry_type  typ_geo_med;
457   med_entity_type    typ_ent_med;
458 
459   med_err            ret_med = 0;
460 
461   med_int            nbr_equiv = 0;
462   med_int            ind_equiv = -1;
463   med_int            edim_med;
464   med_int            nbr_ele_med;
465   med_int            taille_med;
466 
467   med_int          * connect_med = NULL;
468   med_int          * fam_ele_med = NULL;
469 
470   med_bool           changement = MED_FALSE;
471   med_bool           transformation = MED_FALSE;
472   med_int            nstep = 0;
473   med_int            nocstpcorrespondence = 0;
474   med_data_type      data_type = MED_CONNECTIVITY;
475 
476   const int          n_typ_geo_ignore = 3;
477   med_geometry_type  typ_geo_med_ignore[] = {MED_POINT1,
478                                              MED_SEG2,
479                                              MED_SEG3};
480   const char        *nom_typ_ignore[] = {"point1", "seg2", "seg3"};
481 
482   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
483 
484   /*====================================================*/
485   /* Initialisations et allocations des tableaux locaux */
486   /*====================================================*/
487 
488   /* Attention au decalage de `1' !!!         */
489   /* On n'alloue pas les tableaux locaux pour */
490   /* `ECS_ENTMAIL_DEB = ECS_ENTMAIL_SOM'      */
491 
492   for (ient = ECS_ENTMAIL_FAC; ient < ECS_N_ENTMAIL; ient++) {
493 
494     cpt_elt_ent        [ient] = 0;
495 
496     elt_pos_som_ent    [ient] = NULL;
497     elt_val_som_ent    [ient] = NULL;
498     elt_val_fam_ent    [ient] = NULL;
499 
500   }
501 
502   strcpy(nom_maillage_med, nom_maillage);
503 
504   /*------------------------------------------------*/
505   /* Lecture de la connectivité nodale des elements */
506   /*------------------------------------------------*/
507 
508   for (ityp = 0; ityp < n_typ_geo_ignore; ityp++) {
509 
510     /* On regarde si le maillage MED comporte des éléments ignorés */
511     /*-------------------------------------------------------------*/
512 
513     nbr_ele_med = MEDmeshnEntity(fic_maillage->fid,
514                                  nom_maillage_med,
515                                  MED_NO_DT,
516                                  MED_NO_IT,
517                                  MED_NODE,
518                                  typ_geo_med_ignore[ityp],
519                                  MED_CONNECTIVITY,
520                                  MED_NODAL,
521                                  &changement,
522                                  &transformation);
523 
524     if (nbr_ele_med < 0)
525       ret_med = -1;
526 
527     else if (nbr_ele_med == 0) {
528 
529       nbr_ele_med = MEDmeshnEntity(fic_maillage->fid,
530                                    nom_maillage_med,
531                                    MED_NO_DT,
532                                    MED_NO_IT,
533                                    MED_CELL,
534                                    typ_geo_med_ignore[ityp],
535                                    MED_CONNECTIVITY,
536                                    MED_NODAL,
537                                    &changement,
538                                    &transformation);
539 
540       if (nbr_ele_med < 0)
541         ret_med = -1;
542 
543     }
544 
545     if (ret_med != 0)
546       ecs_error(__FILE__, __LINE__, 0,
547                 _("MED: error reading file \"%s\".\n"
548                   "Number of elements of entity read: \"%d\"."),
549                 fic_maillage->nom_fic, (int)nbr_ele_med);
550 
551     if (nbr_ele_med != 0) {
552 
553       ecs_warn();
554       printf(_("The MED mesh contains %d elements of type %s\n"
555                "which are ignored by the Preprocessor.\n\n"),
556              (int)nbr_ele_med, nom_typ_ignore[ityp]);
557 
558     }
559   }
560 
561   /* Vérification du nombre d'équivalences
562      (pour connectivité faces non conformes éventuelle) */
563 
564   nbr_equiv = MEDnEquivalence(fic_maillage->fid,
565                               nom_maillage_med);
566 
567   if (nbr_equiv < 0)
568     ecs_error(__FILE__, __LINE__, 0,
569               _("MED: error reading file \"%s\".\n"
570                 "Error reading equivalence information."),
571               fic_maillage->nom_fic);
572 
573   else if (nbr_equiv > 0) {
574 
575     size_t  ind;
576     char nom_equiv_cmp[MED_NAME_SIZE+1];
577     char desc_equiv[MED_COMMENT_SIZE+1];
578 
579     for (ind_equiv = 0; ind_equiv < nbr_equiv; ind_equiv++) {
580 
581       ret_med = MEDequivalenceInfo(fic_maillage->fid,
582                                    nom_maillage_med,
583                                    ind_equiv + 1,
584                                    nom_equiv,
585                                    desc_equiv,
586                                    &nstep,
587                                    &nocstpcorrespondence);
588 
589       if (ret_med < 0)
590         ecs_error(__FILE__, __LINE__, 0,
591                   _("MED: error reading file \"%s\".\n"
592                     "Error reading equivalence information."),
593                   fic_maillage->nom_fic);
594 
595       nom_equiv[MED_NAME_SIZE] = '\0';
596 
597       for (ind = 0; ind < MED_NAME_SIZE && nom_equiv[ind] != '\0'; ind++)
598         nom_equiv_cmp[ind] = tolower(nom_equiv[ind]);
599       nom_equiv_cmp[strlen(nom_equiv)] = '\0';
600 
601       if (   strcmp(nom_equiv_cmp, "face_connectivity") == 0
602           || strcmp(nom_equiv_cmp, "face connectivity") == 0)
603         break;
604 
605     }
606 
607     if (ind_equiv >= nbr_equiv) {
608       nom_equiv[0] = '\0';
609       ind_equiv = -1;
610     }
611 
612   }
613 
614   /* Boucle sur tous les types géométriques MED référencés dans l'Enveloppe */
615   /*------------------------------------------------------------------------*/
616 
617   for (ityp = 0; ityp < ECS_MED_NBR_TYP_ELT; ityp++) {
618 
619     taille_med = 0;
620     typ_geo_med = ecs_fic_med_init_elt_liste_c[ityp].med_typ;
621 
622     /*
623      * On essaiera de lire en priorité les mailles, les arêtes ou faces
624      * correspondant à une connectivité descendante étant lues en second choix.
625      */
626 
627     edim_med = typ_geo_med / 100;
628 
629     typ_ent_med = MED_CELL;
630 
631     nbr_ele_med = MEDmeshnEntity(fic_maillage->fid,
632                                  nom_maillage_med,
633                                  MED_NO_DT,
634                                  MED_NO_IT,
635                                  typ_ent_med,
636                                  typ_geo_med,
637                                  MED_CONNECTIVITY,
638                                  MED_NODAL,
639                                  &changement,
640                                  &transformation);
641 
642     if (nbr_ele_med > 0) { /* Special case for polygons and polyhedra */
643 
644       if (typ_geo_med == MED_POLYGON)
645         data_type = MED_INDEX_NODE;
646       else if (typ_geo_med == MED_POLYHEDRON)
647         data_type = MED_INDEX_FACE;
648 
649       if (data_type != MED_CONNECTIVITY)
650         nbr_ele_med = MEDmeshnEntity(fic_maillage->fid,
651                                      nom_maillage_med,
652                                      MED_NO_DT,
653                                      MED_NO_IT,
654                                      typ_ent_med,
655                                      typ_geo_med,
656                                      data_type,
657                                      MED_NODAL,
658                                      &changement,
659                                      &transformation) - 1;
660 
661     }
662 
663     if (nbr_ele_med < 0)
664       ret_med = -1;
665 
666     else if (nbr_ele_med == 0 && edim_med <= 2) {
667 
668       if (edim_med == 1)
669         typ_ent_med = MED_DESCENDING_EDGE;
670       else if (edim_med == 2)
671         typ_ent_med = MED_DESCENDING_FACE;
672 
673       nbr_ele_med = MEDmeshnEntity(fic_maillage->fid,
674                                    nom_maillage_med,
675                                    MED_NO_DT,
676                                    MED_NO_IT,
677                                    typ_ent_med,
678                                    typ_geo_med,
679                                    MED_CONNECTIVITY,
680                                    MED_NODAL,
681                                    &changement,
682                                    &transformation);
683 
684       if (nbr_ele_med < 0)
685         ret_med = -1;
686 
687     }
688 
689     if (ret_med != 0)
690       ecs_error(__FILE__, __LINE__, 0,
691                 _("MED: error reading file \"%s\".\n"
692                   "Number of elements of entity read: \"%d\"."),
693                 fic_maillage->nom_fic, (int)nbr_ele_med);
694 
695     if (nbr_ele_med != 0) {
696 
697       nbr_elt = (ecs_int_t)nbr_ele_med;
698 
699       /* Type géometrique */
700       /*------------------*/
701 
702       typ_geo_ecs = ecs_fic_med_init_elt_liste_c[ityp].ecs_typ;
703 
704       /* Identification de l'entité concernée */
705       /*--------------------------------------*/
706 
707       entmail_e = ecs_maillage_pre__ret_typ_geo(typ_geo_ecs);
708 
709       ECS_REALLOC(elt_pos_som_ent[entmail_e],
710                   cpt_elt_ent[entmail_e] + 1 + nbr_elt, ecs_size_t);
711 
712       if (cpt_elt_ent[entmail_e] == 0) {
713         /* On est au 1er tour */
714         elt_pos_som_ent[entmail_e][0] = 1;
715       }
716 
717       ECS_REALLOC(elt_val_fam_ent[entmail_e],
718                   cpt_elt_ent[entmail_e] + nbr_elt, int);
719 
720       ECS_MALLOC(fam_ele_med, nbr_ele_med, med_int);
721 
722       /* Traitement des éléments "classiques" */
723       /*--------------------------------------*/
724 
725       if (typ_geo_med != MED_POLYGON && typ_geo_med != MED_POLYHEDRON) {
726 
727         nbr_som_elt = ecs_fic_elt_typ_liste_c[typ_geo_ecs].nbr_som;
728 
729         taille = elt_pos_som_ent[entmail_e][cpt_elt_ent[entmail_e]] - 1;
730 
731         ECS_REALLOC(elt_val_som_ent[entmail_e],
732                     taille + nbr_elt * nbr_som_elt, ecs_int_t);
733 
734 
735         /* Convention sur la taille des mailles */
736 
737         edim_med = typ_geo_med / 100;
738         taille_med = typ_geo_med % 100;
739 
740         taille = (ecs_int_t)nbr_ele_med * (ecs_int_t)taille_med;
741         ECS_MALLOC(connect_med, taille, med_int);
742 
743         ret_med = MEDmeshElementConnectivityRd(fic_maillage->fid,
744                                                nom_maillage_med,
745                                                MED_NO_DT,
746                                                MED_NO_IT,
747                                                typ_ent_med,
748                                                typ_geo_med,
749                                                MED_NODAL,
750                                                MED_FULL_INTERLACE,
751                                                connect_med);
752 
753         if (ret_med != 0)
754           ecs_error(__FILE__, __LINE__, 0,
755                     _("MED: error reading file \"%s\".\n"
756                       "Error reading connectivity."),
757                     fic_maillage->nom_fic);
758 
759         /* Les références aux noeuds milieux des éléments     */
760         /*  quadratiques ne sont pas conservées               */
761 
762         elt_val_som = ecs_loc_convert_connect_med_ecs(connect_med,
763                                                       taille,
764                                                       taille_med,
765                                                       nbr_som_elt);
766 
767         /* Remplissage de la connectivité */
768 
769         cpt_som = 0;
770 
771         for (ielt = 0; ielt < nbr_elt; ielt++) {
772 
773           pos_elt = elt_pos_som_ent[entmail_e][cpt_elt_ent[entmail_e]
774                                                + ielt];
775 
776           elt_pos_som_ent[entmail_e][cpt_elt_ent[entmail_e] + ielt + 1]
777             = pos_elt + nbr_som_elt;
778 
779           for (isom = 0; isom < nbr_som_elt; isom++) {
780 
781             renum_som = ecs_fic_med_init_elt_liste_c[ityp].num_som[isom] - 1;
782             elt_val_som_ent[entmail_e][pos_elt - 1 + isom]
783               = elt_val_som[cpt_som + renum_som];
784 
785           }
786 
787           cpt_som += nbr_som_elt;
788         }
789 
790         /* Libération connectivité temporaire */
791 
792         ECS_FREE(elt_val_som);
793       }
794 
795       /* Traitement des polygones */
796       /*--------------------------*/
797 
798       else if (typ_geo_med == MED_POLYGON) {
799 
800         ecs_int_t    ival;
801         ecs_int_t    nbr_val_elt;
802         med_int    * index_med = NULL;
803 
804         /* Taille du tableau des connectivites */
805 
806         taille_med = MEDmeshnEntity(fic_maillage->fid,
807                                     nom_maillage_med,
808                                     MED_NO_DT,
809                                     MED_NO_IT,
810                                     typ_ent_med,
811                                     MED_POLYGON,
812                                     MED_CONNECTIVITY,
813                                     MED_NODAL,
814                                     &changement,
815                                     &transformation);
816 
817         if (taille_med < 0)
818           ret_med = -1;
819 
820         if (ret_med != 0)
821           ecs_error(__FILE__, __LINE__, 0,
822                     _("MED: error reading file \"%s\".\n"
823                       "(polygons information)."),
824                     fic_maillage->nom_fic);
825 
826         taille = elt_pos_som_ent[entmail_e][cpt_elt_ent[entmail_e]] - 1;
827 
828         ECS_REALLOC(elt_val_som_ent[entmail_e],
829                     taille + (ecs_int_t)taille_med, ecs_int_t);
830 
831         ECS_MALLOC(index_med, (ecs_int_t)(nbr_ele_med + 1), med_int);
832         ECS_MALLOC(connect_med, (ecs_int_t)taille_med, med_int);
833 
834         /* Lecture de la connectivité des polygones */
835 
836         ret_med = MEDmeshPolygonRd(fic_maillage->fid,
837                                    nom_maillage_med,
838                                    MED_NO_DT,
839                                    MED_NO_IT,
840                                    typ_ent_med,
841                                    MED_NODAL,
842                                    index_med,
843                                    connect_med);
844 
845         if (ret_med != 0)
846           ecs_error(__FILE__, __LINE__, 0,
847                     _("MED: error reading file \"%s\".\n"
848                       "(polygons connectivity)."),
849                     fic_maillage->nom_fic);
850 
851         /* Remplissage de la connectivité */
852 
853         pos_elt = elt_pos_som_ent[entmail_e][cpt_elt_ent[entmail_e]];
854 
855         for (ielt = 0; ielt < nbr_elt; ielt++)
856           elt_pos_som_ent[entmail_e][cpt_elt_ent[entmail_e] + ielt + 1]
857             = pos_elt + index_med[ielt + 1] - index_med[0];
858 
859         nbr_val_elt = index_med[nbr_elt] - index_med[0];
860 
861         for (ival = 0; ival < nbr_val_elt; ival++)
862           elt_val_som_ent[entmail_e][pos_elt - 1 + ival]
863             = connect_med[ival];
864 
865         /* Libération connectivité temporaire */
866 
867         ECS_FREE(index_med);
868         ECS_FREE(connect_med);
869 
870       }
871 
872       /* Traitement des polyèdres */
873       /*--------------------------*/
874 
875       else if (typ_geo_med == MED_POLYHEDRON) {
876 
877         ecs_int_t    ifac, ival;
878         ecs_int_t    num_som_prec, num_som_deb;
879         ecs_int_t    cpt_som_poly_dup = 0;
880         ecs_int_t    cpt_fac_poly_dgn = 0;
881         med_int      n_index_f_med = 0;
882         med_int    * index_med = NULL;
883         med_int    * index_f_med = NULL;
884 
885         /* Taille du tableau des connectivites */
886 
887         ret_med = 0;
888 
889         n_index_f_med = MEDmeshnEntity(fic_maillage->fid,
890                                        nom_maillage_med,
891                                        MED_NO_DT,
892                                        MED_NO_IT,
893                                        typ_ent_med,
894                                        MED_POLYHEDRON,
895                                        MED_INDEX_NODE,
896                                        MED_NODAL,
897                                        &changement,
898                                        &transformation);
899 
900         if (n_index_f_med < 0)
901           ret_med = -1;
902 
903         if (ret_med >= 0) {
904 
905           taille_med = MEDmeshnEntity(fic_maillage->fid,
906                                       nom_maillage_med,
907                                       MED_NO_DT,
908                                       MED_NO_IT,
909                                       typ_ent_med,
910                                       MED_POLYHEDRON,
911                                       MED_CONNECTIVITY,
912                                       MED_NODAL,
913                                       &changement,
914                                       &transformation);
915 
916           if (taille_med < 0)
917             ret_med = -1;
918 
919         }
920 
921         if (ret_med != 0)
922           ecs_error(__FILE__, __LINE__, 0,
923                     _("MED: error reading file \"%s\".\n"
924                       "(polyhedra information)."),
925                     fic_maillage->nom_fic);
926 
927         /* On ajoute le nombre de faces (n_index_f_med - 1) à la taille du
928            tableau destiné à recevoir la connectivité afin de faire apparaître
929            une seconde fois le numéro du premier sommet à la fin de la liste
930            des sommets de chaque face dans la définition des cellules (pour
931            repérer la fin de définition de chaque face d'une cellule). */
932 
933         taille = elt_pos_som_ent[entmail_e][cpt_elt_ent[entmail_e]] - 1;
934 
935         ECS_REALLOC(elt_val_som_ent[entmail_e],
936                     taille + (ecs_int_t)(taille_med + n_index_f_med - 1),
937                     ecs_int_t);
938 
939         ECS_MALLOC(index_med, (ecs_int_t)(nbr_ele_med + 1), med_int);
940         ECS_MALLOC(index_f_med, (ecs_int_t)(n_index_f_med), med_int);
941         ECS_MALLOC(connect_med, (ecs_int_t)taille_med, med_int);
942 
943         /* Lecture de la connectivité des polyèdres */
944 
945         ret_med = MEDmeshPolyhedronRd(fic_maillage->fid,
946                                       nom_maillage_med,
947                                       MED_NO_DT,
948                                       MED_NO_IT,
949                                       typ_ent_med,
950                                       MED_NODAL,
951                                       index_med,
952                                       index_f_med,
953                                       connect_med);
954 
955         if (ret_med != 0)
956           ecs_error(__FILE__, __LINE__, 0,
957                     _("MED: error reading file \"%s\".\n"
958                       "(polyhedra connectivity)."),
959                     fic_maillage->nom_fic);
960 
961         if (index_med[nbr_ele_med] - index_med[0] + 1 != n_index_f_med)
962           ecs_error
963             (__FILE__, __LINE__, 0,
964              _("MED: inconsistency in polyhedra connectivity;\n"
965                "number of polyhedra: %d\n"
966                "the cells->faces end index (%d) should be equal to\n"
967                "the size of the faces->vertices index array (%d)\n"),
968              (int) nbr_ele_med,
969              (int)(index_med[nbr_ele_med] - index_med[0] + 1),
970              (int) n_index_f_med);
971 
972         /* Remplissage de la connectivité */
973 
974         pos_elt = elt_pos_som_ent[entmail_e][cpt_elt_ent[entmail_e]];
975 
976         ival = pos_elt - 1;
977 
978         for (ielt = 0; ielt < nbr_elt; ielt++) {
979 
980           for (ifac = index_med[ielt    ] - index_med[0];
981                ifac < index_med[ielt + 1] - index_med[0];
982                ifac++) {
983 
984             /* Premier sommet de la face */
985 
986             isom = index_f_med[ifac    ] - index_f_med[0];
987 
988             elt_val_som_ent[entmail_e][ival++] = connect_med[isom];
989 
990             num_som_prec = connect_med[isom];
991             num_som_deb  = connect_med[isom];
992 
993             nbr_som_fac = 1;
994 
995             /* Autres sommets de la face */
996 
997             for (isom = index_f_med[ifac    ] - index_f_med[0] + 1;
998                  isom < index_f_med[ifac + 1] - index_f_med[0];
999                  isom++) {
1000 
1001               if (   connect_med[isom] != num_som_prec
1002                   && connect_med[isom] != num_som_deb) {
1003                 elt_val_som_ent[entmail_e][ival++] = connect_med[isom];
1004                 num_som_prec = connect_med[isom];
1005                 nbr_som_fac += 1;
1006               }
1007               else
1008                 cpt_som_poly_dup += 1;
1009 
1010             }
1011 
1012             /* Si la face est dégénérée (1 ou 2 sommets), on la supprime */
1013 
1014             if (nbr_som_fac < 3) {
1015 
1016               ival -= nbr_som_fac;
1017               cpt_fac_poly_dgn += 1;
1018 
1019             }
1020             else {
1021 
1022               /* On rajoute une seconde référence au premier sommet de
1023                  chaque face en fin de liste pour "fermer" cette face
1024                  (convention polyèdre Enveloppe Code_Saturne pour repérer
1025                  les faces d'un polyèdre en connectivité nodale) */
1026 
1027               isom = index_f_med[ifac    ] - index_f_med[0];
1028 
1029               elt_val_som_ent[entmail_e][ival++] = connect_med[isom];
1030 
1031             }
1032 
1033           }
1034 
1035           elt_pos_som_ent[entmail_e][cpt_elt_ent[entmail_e] + ielt + 1]
1036             = ival + 1;
1037 
1038         }
1039 
1040         assert((size_t)(taille_med + n_index_f_med - 1)
1041                >= (size_t)((  elt_pos_som_ent[entmail_e]
1042                                              [cpt_elt_ent[entmail_e] + ielt]
1043                             - elt_pos_som_ent[entmail_e]
1044                                              [cpt_elt_ent[entmail_e]])
1045                            + cpt_som_poly_dup + cpt_fac_poly_dgn));
1046 
1047         if (cpt_som_poly_dup > 0) {
1048 
1049           ecs_warn();
1050           printf(_("While reading file \"%s\",\n"
1051                    "%d repeated references to the same vertices\n"
1052                    "and %d degenerate faces were encountered\n"
1053                    "in the definition of %d polyhedra.\n"),
1054                  fic_maillage->nom_fic, (int) cpt_som_poly_dup,
1055                  (int) cpt_fac_poly_dgn, (int) nbr_elt);
1056 
1057           ECS_REALLOC (elt_val_som_ent[entmail_e], ival + 1, ecs_int_t);
1058 
1059         }
1060 
1061         /* Libération connectivité temporaire */
1062 
1063         ECS_FREE(index_med);
1064         ECS_FREE(index_f_med);
1065         ECS_FREE(connect_med);
1066 
1067       }
1068 
1069       /* Lecture des numéros de familles */
1070 
1071       ret_med = MEDmeshEntityFamilyNumberRd(fic_maillage->fid,
1072                                             nom_maillage_med,
1073                                             MED_NO_DT,
1074                                             MED_NO_IT,
1075                                             typ_ent_med,
1076                                             typ_geo_med,
1077                                             fam_ele_med);
1078 
1079       /* Convention MED : si pas de familles, numéros = 0 */
1080 
1081       if (ret_med < 0) {
1082         for (ielt = 0; ielt < nbr_elt; ielt++)
1083           fam_ele_med[ielt] = 0;
1084         ret_med = 0;
1085       }
1086       else if (ret_med > 0) {
1087         ecs_warn();
1088         printf(_("MED: erreur reading file \"%s\".\n"
1089                  "(families)."),
1090                fic_maillage->nom_fic);
1091       }
1092 
1093       /* Changement de signe pour les familles des éléments */
1094 
1095       for (ielt = 0; ielt < nbr_elt; ielt++) {
1096 
1097         elt_val_fam_ent[entmail_e][cpt_elt_ent[entmail_e] + ielt]
1098           = -fam_ele_med[ielt];
1099 
1100       }
1101 
1102       ECS_FREE(fam_ele_med);
1103 
1104       /* Lecture éventuelle des connectivités */
1105 
1106       if (edim_med == 2 && ind_equiv >= 0) {
1107 
1108         size_t  n_corres_old = maillage->n_connect_couples[ECS_ENTMAIL_FAC];
1109         med_int nbr_corres;
1110         med_int *corres = NULL;
1111         ecs_int_t *copy_fac_connect = NULL;
1112 
1113         ret_med = MEDequivalenceCorrespondenceSize(fic_maillage->fid,
1114                                                    nom_maillage_med,
1115                                                    nom_equiv,
1116                                                    MED_NO_DT,
1117                                                    MED_NO_IT,
1118                                                    typ_ent_med,
1119                                                    typ_geo_med,
1120                                                    &nbr_corres);
1121 
1122         if (ret_med < 0)
1123           ecs_error(__FILE__, __LINE__, 0,
1124                     _("MED: error reading file \"%s\".\n"
1125                       "Error reading equivalence information."),
1126                     fic_maillage->nom_fic);
1127 
1128         else if (nbr_corres > 0) {
1129 
1130           maillage->n_connect_couples[ECS_ENTMAIL_FAC] += nbr_corres;
1131 
1132           ECS_REALLOC(maillage->connect_couples[ECS_ENTMAIL_FAC],
1133                       maillage->n_connect_couples[ECS_ENTMAIL_FAC] * 2,
1134                       ecs_int_t);
1135 
1136           ECS_MALLOC(corres, nbr_corres*2, med_int);
1137 
1138           ret_med = MEDequivalenceCorrespondenceRd(fic_maillage->fid,
1139                                                    nom_maillage_med,
1140                                                    nom_equiv,
1141                                                    MED_NO_DT,
1142                                                    MED_NO_IT,
1143                                                    typ_ent_med,
1144                                                    typ_geo_med,
1145                                                    corres);
1146 
1147         }
1148 
1149         /* Add new connected faces, shifting numbering in case of
1150            previously read element types. */
1151 
1152         copy_fac_connect
1153           = maillage->connect_couples[ECS_ENTMAIL_FAC] + (n_corres_old*2);
1154 
1155         for (ielt = 0; ielt < nbr_corres*2; ielt++)
1156           copy_fac_connect[ielt] = corres[ielt] + cpt_elt_ent[entmail_e];
1157 
1158         ECS_FREE(corres);
1159       }
1160 
1161       cpt_elt_ent[entmail_e] += nbr_elt;
1162 
1163     } /* Fin : si le nombre d'éléments de ce type MED n'est pas nul */
1164 
1165   } /* Fin : boucle sur les types d'elements MED supportés */
1166 
1167   /* Transfert des valeurs lues dans les structures d'entité de maillage */
1168   /*=====================================================================*/
1169 
1170   ecs_maillage_pre__cree_elt(maillage,
1171                              cpt_elt_ent,
1172                              elt_pos_som_ent,
1173                              elt_val_som_ent,
1174                              elt_val_fam_ent,
1175                              NULL,
1176                              NULL,
1177                              NULL,
1178                              NULL);
1179 }
1180 
1181 /*----------------------------------------------------------------------------
1182  *                        Lecture des familles
1183  *----------------------------------------------------------------------------*/
1184 
1185 static ecs_famille_t **
ecs_loc_pre_med__lit_famille(const ecs_med_t * fic_maillage,const char * nom_maillage)1186 ecs_loc_pre_med__lit_famille(const ecs_med_t  *fic_maillage,
1187                              const char       *nom_maillage)
1188 {
1189   char                *nom;
1190 
1191   ecs_int_t            deb_pos_sans_blanc;
1192   ecs_int_t            fin_pos_sans_blanc;
1193   ecs_int_t            icar;
1194   ecs_int_t            ide;
1195   ecs_int_t            ifam;
1196   ecs_int_t            ifam_ent;
1197   ecs_int_t            nbr_car;
1198   ecs_int_t            nbr_famille_ent[ECS_N_ENTMAIL];
1199   ecs_int_t            num_fam;
1200   ecs_int_t            num_fam_ent;
1201   ecs_descr_t         *descr;
1202   ecs_descr_t         *descr_tete;
1203 
1204   ecs_famille_t       *famille;
1205   ecs_famille_t     **vect_famille_tete;
1206   ecs_famille_t     **liste_famille_ent[ECS_N_ENTMAIL];
1207 
1208   /* Declarations des variables pour MED */
1209   /*-------------------------------------*/
1210 
1211   char       nom_maillage_med[MED_NAME_SIZE + 1];
1212   char      *att_des_med;
1213   char      *grp_des_med;
1214   char       nom_fam_med[MED_NAME_SIZE + 1];
1215   char       un_att_des_med[MED_COMMENT_SIZE + 1];
1216   char       un_grp_des_med[MED_LNAME_SIZE + 1];
1217 
1218   med_err    ret_med = 0;
1219 
1220   med_int    iatt_med;
1221   med_int    ifam_med;
1222   med_int    igrp_med;
1223   med_int    nbr_fam_med;
1224   med_int    nbr_att_med;
1225   med_int    nbr_grp_med;
1226   med_int    num_fam_med;
1227   med_int   *att_ide_med;
1228   med_int   *att_val_med;
1229 
1230   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1231 
1232   strcpy(nom_maillage_med, nom_maillage);
1233 
1234   /* On récupere le nombre de familles */
1235 
1236   nbr_fam_med = MEDnFamily(fic_maillage->fid,
1237                            nom_maillage_med);
1238 
1239   if (nbr_fam_med < 0)
1240     ret_med = -1;
1241 
1242   if (ret_med != 0)
1243     ecs_error(__FILE__, __LINE__, 0,
1244               _("MED: error reading file \"%s\".\n"
1245                 "Number of families read: \"%d\""),
1246               fic_maillage->nom_fic, (int)nbr_fam_med);
1247 
1248   for (ifam_ent = 0; ifam_ent < ECS_N_ENTMAIL; ifam_ent++) {
1249 
1250     nbr_famille_ent[ifam_ent] = 0;
1251     ECS_MALLOC(liste_famille_ent[ifam_ent],
1252                (ecs_int_t)nbr_fam_med, ecs_famille_t *);
1253 
1254   }
1255 
1256   ECS_MALLOC(vect_famille_tete, ECS_N_ENTMAIL, ecs_famille_t *);
1257   for (ifam_ent = 0; ifam_ent < ECS_N_ENTMAIL; ifam_ent++)
1258     vect_famille_tete[ifam_ent] = NULL;
1259 
1260   /*----------------------*/
1261   /* Lecture des familles */
1262   /*----------------------*/
1263 
1264   for (ifam_med = 0; ifam_med < nbr_fam_med; ifam_med++) {
1265 
1266     /*------------------------------------*/
1267     /* Récupération du nombre d'attributs */
1268     /*------------------------------------*/
1269 
1270     if (fic_maillage->version[0] == 2)
1271       nbr_att_med = MEDnFamily23Attribute(fic_maillage->fid,
1272                                           nom_maillage_med,
1273                                           ifam_med + 1);
1274     else
1275       nbr_att_med = 0;
1276 
1277     if (nbr_att_med < 0)
1278       ret_med = -1;
1279 
1280     if (ret_med != 0)
1281       ecs_error(__FILE__, __LINE__, 0,
1282                 _("MED: error reading file \"%s\".\n"
1283                   "Number of attributes read: \"%d\""),
1284                 fic_maillage->nom_fic, (int)nbr_att_med);
1285 
1286     /*-----------------------------------*/
1287     /* Récupération du nombre de groupes */
1288     /*-----------------------------------*/
1289 
1290     nbr_grp_med = MEDnFamilyGroup(fic_maillage->fid,
1291                                   nom_maillage_med,
1292                                   ifam_med + 1);
1293 
1294     if (nbr_grp_med < 0)
1295       ret_med = -1;
1296 
1297     if (ret_med != 0)
1298       ecs_error(__FILE__, __LINE__, 0,
1299                 _("MED: error reading file \"%s\".\n"
1300                   "Number of groups read: \"%d\""),
1301                 fic_maillage->nom_fic, (int)nbr_grp_med);
1302 
1303     /*--------------------------------------*/
1304     /* Lecture des attributs et des groupes */
1305     /*--------------------------------------*/
1306 
1307     if (nbr_att_med != 0) {
1308 
1309       ECS_MALLOC(att_ide_med, nbr_att_med, med_int);
1310       ECS_MALLOC(att_val_med, nbr_att_med, med_int);
1311       ECS_MALLOC(att_des_med, nbr_att_med * MED_COMMENT_SIZE + 1, char);
1312 
1313     }
1314     else {
1315 
1316       att_ide_med = NULL;
1317       att_val_med = NULL;
1318       att_des_med = NULL;
1319 
1320     }
1321 
1322     ECS_MALLOC(grp_des_med, nbr_grp_med * MED_LNAME_SIZE + 1, char);
1323 
1324     if (fic_maillage->version[0] == 2)
1325       ret_med = MEDfamily23Info(fic_maillage->fid,
1326                                 nom_maillage_med,
1327                                 ifam_med + 1,
1328                                 nom_fam_med,
1329                                 att_ide_med,
1330                                 att_val_med,
1331                                 att_des_med,
1332                                 &num_fam_med,
1333                                 grp_des_med);
1334 
1335     else
1336       ret_med = MEDfamilyInfo(fic_maillage->fid,
1337                               nom_maillage_med,
1338                               ifam_med + 1,
1339                               nom_fam_med,
1340                               &num_fam_med,
1341                               grp_des_med);
1342 
1343     if (num_fam_med != 0) {
1344 
1345       descr_tete = NULL;
1346 
1347       if (nbr_att_med == 0 && nbr_grp_med == 0)
1348         printf(_("  Family %2d is described by no attribute or group.\n"),
1349                (int)(ECS_ABS(num_fam_med)));
1350 
1351       for (iatt_med = 0; iatt_med < nbr_att_med; iatt_med++) {
1352 
1353         /* Récupération de la valeur entière du descripteur */
1354         /*--------------------------------------------------*/
1355 
1356         ide =  (ecs_int_t)att_val_med[iatt_med];
1357 
1358         /* Recupération du descripteur */
1359         /*-----------------------------*/
1360 
1361         strncpy(un_att_des_med,
1362                 att_des_med + iatt_med * MED_COMMENT_SIZE, MED_COMMENT_SIZE);
1363         un_att_des_med[MED_COMMENT_SIZE] = '\0';
1364 
1365         /* On regarde si la chaîne ne contient pas que des blancs */
1366         /* On ne garde que la partie de la chaîne                 */
1367         /*  qui n'a pas de blancs aux extrémités                  */
1368 
1369         deb_pos_sans_blanc = 0;
1370         while (*(un_att_des_med + deb_pos_sans_blanc) != '\0' &&
1371                *(un_att_des_med + deb_pos_sans_blanc) == ' ')
1372           deb_pos_sans_blanc++;
1373 
1374         for (fin_pos_sans_blanc = deb_pos_sans_blanc;
1375              (   fin_pos_sans_blanc < MED_COMMENT_SIZE - 1
1376                && *(un_att_des_med + fin_pos_sans_blanc) != '\0');
1377              fin_pos_sans_blanc++);
1378 
1379         if (   fin_pos_sans_blanc > deb_pos_sans_blanc
1380             && deb_pos_sans_blanc < MED_COMMENT_SIZE) {
1381 
1382           /* La chaîne ne contient pas que des blancs */
1383 
1384           while (fin_pos_sans_blanc                     != 0    &&
1385                  *(un_att_des_med + fin_pos_sans_blanc) == ' ')
1386             fin_pos_sans_blanc--;
1387 
1388           nbr_car = fin_pos_sans_blanc - deb_pos_sans_blanc + 1;
1389           ECS_MALLOC(nom, nbr_car + 1, char);
1390           for (icar = 0; icar < nbr_car; icar++)
1391             *(nom + icar) = *(un_att_des_med + deb_pos_sans_blanc + icar);
1392           *(nom + nbr_car) = '\0';
1393 
1394         }
1395         else {
1396           nom   = NULL;
1397         }
1398 
1399         descr = ecs_descr__cree(ide, nom);
1400 
1401         ecs_descr_chaine__ajoute(&descr_tete, descr);
1402 
1403         if (nom != NULL)
1404           ECS_FREE(nom);
1405 
1406       } /* Fin : boucle sur les attributs de la famille */
1407 
1408       for (igrp_med = 0; igrp_med < nbr_grp_med; igrp_med++) {
1409 
1410         /* Récuperation de la chaîne de caracteres du descripteur */
1411 
1412         strncpy(un_grp_des_med,
1413                 grp_des_med + igrp_med * MED_LNAME_SIZE, MED_LNAME_SIZE);
1414         un_grp_des_med[MED_LNAME_SIZE] = '\0';
1415 
1416         /* On regarde si la chaîne ne contient pas que des blancs */
1417         /* On ne garde que la partie de la chaîne                 */
1418         /*  qui n'a pas de blancs aux extrémités                  */
1419 
1420         deb_pos_sans_blanc = 0;
1421         while (*(un_grp_des_med + deb_pos_sans_blanc) != '\0' &&
1422                *(un_grp_des_med + deb_pos_sans_blanc) == ' ')
1423           deb_pos_sans_blanc++;
1424 
1425         /* On verifie que la chaîne ne contient pas que des blancs */
1426         assert(deb_pos_sans_blanc < MED_LNAME_SIZE + 1);
1427 
1428         fin_pos_sans_blanc = MED_LNAME_SIZE - 1;
1429         while (fin_pos_sans_blanc              != 0    &&
1430                *(un_grp_des_med + fin_pos_sans_blanc) == ' ')
1431           fin_pos_sans_blanc--;
1432 
1433         nbr_car = fin_pos_sans_blanc - deb_pos_sans_blanc + 1;
1434         ECS_MALLOC(nom, nbr_car + 1, char);
1435         for (icar = 0; icar < nbr_car; icar++)
1436           *(nom + icar) = *(un_grp_des_med + deb_pos_sans_blanc + icar);
1437         *(nom + nbr_car) = '\0';
1438 
1439 
1440         /* Pas de valeur entière associée */
1441 
1442         descr = ecs_descr__cree(ECS_DESCR_IDE_NUL, nom);
1443 
1444         ecs_descr_chaine__ajoute(&descr_tete, descr);
1445 
1446         if (nom != NULL)
1447           ECS_FREE(nom);
1448 
1449       } /* Fin : boucle sur les groupes de la famille */
1450 
1451 
1452       /* Détermination de l'entité concernée par la famille */
1453 
1454       if (num_fam_med < 0) {
1455 
1456         /* On accroche toutes les familles des éléments */
1457         /*  sur les familles des cellules               */
1458 
1459         num_fam_ent = ECS_ENTMAIL_CEL;
1460 
1461         num_fam = (ecs_int_t)num_fam_med;
1462 
1463         famille = ecs_famille__cree(num_fam, descr_tete);
1464 
1465         liste_famille_ent[num_fam_ent][nbr_famille_ent[num_fam_ent]] = famille;
1466         nbr_famille_ent[num_fam_ent]++;
1467 
1468       }
1469       else {
1470 
1471         num_fam_ent = ECS_ENTMAIL_NONE;
1472 
1473       }
1474 
1475     } /* Fin : si la famille n'est pas la famille par défaut de MED */
1476 
1477     if (nbr_att_med != 0) {
1478 
1479       ECS_FREE(att_ide_med);
1480       ECS_FREE(att_val_med);
1481       ECS_FREE(att_des_med);
1482 
1483     }
1484     ECS_FREE(grp_des_med);
1485 
1486   } /* Fin : boucle sur les familles lues */
1487 
1488   for (ifam_ent = 0; ifam_ent < ECS_N_ENTMAIL; ifam_ent++) {
1489 
1490     for (ifam = 0; ifam < nbr_famille_ent[ifam_ent]; ifam++) {
1491 
1492       ecs_famille_chaine__ajoute(&vect_famille_tete[ifam_ent],
1493                                  liste_famille_ent[ifam_ent][ifam]);
1494     }
1495 
1496   }
1497 
1498   for (ifam_ent = 0; ifam_ent < ECS_N_ENTMAIL; ifam_ent++)
1499     ECS_FREE(liste_famille_ent[ifam_ent]);
1500 
1501   return vect_famille_tete;
1502 }
1503 
1504 /*============================================================================
1505  *                             Fonctions publiques
1506  *============================================================================*/
1507 
1508 /*----------------------------------------------------------------------------
1509  *  Lecture d'un fichier au format MED
1510  *   et affectation des donnees dans la structure de maillage
1511  *----------------------------------------------------------------------------*/
1512 
1513 ecs_maillage_t *
ecs_pre_med__lit_maillage(const char * nom_fic_maillage,int num_maillage)1514 ecs_pre_med__lit_maillage(const char  *nom_fic_maillage,
1515                           int          num_maillage)
1516 {
1517   char            *nom_maillage;
1518   int              ind;
1519   med_int          dim_e;
1520   ecs_med_t       *fic_maillage;
1521   ecs_famille_t  **vect_famille;
1522 
1523   /* Declarations des variables pour MED */
1524   /*-------------------------------------*/
1525 
1526   char           nom_maillage_med[MED_NAME_SIZE + 1];
1527   char           desc_maillage_med[MED_COMMENT_SIZE + 1];
1528 
1529   med_err        ret_med = 0;
1530 
1531   med_int        mdim_med;
1532   med_int        nbr_maillages_med;
1533   int            num_maillage_med = 1;
1534   med_mesh_type  type_maillage_med;
1535 
1536   char              dtunit[MED_LNAME_SIZE + 1];
1537   char              axisname[MED_SNAME_SIZE*3 + 1];
1538   char              axisunit[MED_SNAME_SIZE*3 + 1];
1539   med_sorting_type  sortingtype;
1540   med_int           nstep;
1541   med_axis_type     axistype;
1542 
1543   /* Création d'un maillage initialement vide (valeur de retour) */
1544 
1545   ecs_maillage_t  *maillage = ecs_maillage__cree_nodal();
1546 
1547   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1548 
1549   printf(_("\n\n"
1550            "Reading mesh from file in MED (EDF/CEA) format\n"
1551            "----------------------\n"));
1552 
1553   printf(_("  Mesh file: %s\n\n\n"),
1554          nom_fic_maillage);
1555 
1556   /* Ouverture du fichier MED en lecture */
1557   /*-------------------------------------*/
1558 
1559   fic_maillage = ecs_pre_med__cree(nom_fic_maillage);
1560 
1561   /* Vérification et traitements selon le nombre de maillages */
1562 
1563   nbr_maillages_med = MEDnMesh(fic_maillage->fid);
1564 
1565   if (nbr_maillages_med < 0)
1566     ecs_error(__FILE__, __LINE__, 0,
1567               _("MED: error reading file \"%s\"."),
1568               nom_fic_maillage);
1569 
1570   if (nbr_maillages_med > 1) {
1571     printf(_("\n  The file contains multiple meshes:\n"));
1572     for (ind = 0; ind < nbr_maillages_med; ind++) {
1573       ret_med = MEDmeshInfo(fic_maillage->fid,
1574                             ind + 1,
1575                             nom_maillage_med,
1576                             &dim_e,
1577                             &mdim_med,
1578                             &type_maillage_med,
1579                             desc_maillage_med,
1580                             dtunit,
1581                             &sortingtype,
1582                             &nstep,
1583                             &axistype,
1584                             axisname,
1585                             axisunit);
1586       if (ret_med != 0)
1587         ecs_error(__FILE__, __LINE__, 0,
1588                   _("MED: error reading file \"%s\"."),
1589                   nom_fic_maillage);
1590       printf(_("    Mesh %2d: %s\n"), ind + 1, nom_maillage_med);
1591     }
1592     if (num_maillage == 0)
1593       printf(_("\n  No mesh was specified; the first is read.\n\n"));
1594     else if (num_maillage > 0)
1595       printf(_("\n  Mesh number %d was specified.\n\n"), num_maillage);
1596   }
1597   else if (nbr_maillages_med == 0)
1598     ecs_error(__FILE__, __LINE__, 0,
1599               _("No mesh in file.\n"));
1600 
1601   assert (num_maillage >= 0);
1602   if (num_maillage > nbr_maillages_med)
1603     ecs_error(__FILE__, __LINE__, 0,
1604               _("The specified mesh number (%d) is greater than\n"
1605                 "the number of meshes defined (%d) in file\n%s.\n"),
1606               num_maillage, nbr_maillages_med, nom_fic_maillage);
1607   else
1608     num_maillage_med = ECS_MAX(1, num_maillage);
1609 
1610   ret_med = MEDmeshInfo(fic_maillage->fid,
1611                         num_maillage_med,
1612                         nom_maillage_med,
1613                         &dim_e,
1614                         &mdim_med,
1615                         &type_maillage_med,
1616                         desc_maillage_med,
1617                         dtunit,
1618                         &sortingtype,
1619                         &nstep,
1620                         &axistype,
1621                         axisname,
1622                         axisunit);
1623 
1624   if (ret_med != 0)
1625     ecs_error(__FILE__, __LINE__, 0,
1626               _("MED: error reading file \"%s\".\n"
1627                 "Name of mesh read : \"%s\"\n"
1628                 "Dimension read    : \"%d\""),
1629               nom_fic_maillage, nom_maillage_med, mdim_med);
1630 
1631   nom_maillage_med[MED_NAME_SIZE] = '\0';
1632 
1633   printf(_("  Mesh name: %s\n\n"), nom_maillage_med);
1634 
1635   assert((int)mdim_med == 2 || (int)mdim_med == 3);
1636 
1637   ECS_MALLOC(nom_maillage, strlen(nom_maillage_med) + 1, char);
1638   strcpy(nom_maillage, nom_maillage_med);
1639 
1640   /* Lecture des noeuds */
1641   /*--------------------*/
1642 
1643   ecs_loc_pre_med__lit_noeud(maillage,
1644                              fic_maillage,
1645                              nom_maillage,
1646                              dim_e);
1647 
1648   /* Lecture des elements */
1649   /*----------------------*/
1650 
1651   ecs_loc_pre_med__lit_maille(maillage,
1652                               fic_maillage,
1653                               nom_maillage);
1654 
1655   /* Lecture des familles */
1656   /*----------------------*/
1657 
1658   vect_famille = ecs_loc_pre_med__lit_famille(fic_maillage,
1659                                               nom_maillage);
1660 
1661   ecs_maillage__definit_famille(maillage,
1662                                 vect_famille);
1663 
1664   ECS_FREE(vect_famille);
1665   ECS_FREE(nom_maillage);
1666 
1667   /* Fermeture du fichier de lecture du maillage */
1668   /*---------------------------------------------*/
1669 
1670   ecs_pre_med__detruit(fic_maillage);
1671 
1672   /* Transformation des familles en attributs "groupe" */
1673   /*---------------------------------------------------*/
1674 
1675   ecs_maillage__cree_attributs(maillage);
1676 
1677   return maillage;
1678 }
1679 
1680 /*----------------------------------------------------------------------------*/
1681 
1682 #endif /* HAVE_MED */
1683