Salome HOME
c5dde7ed014759685dbe9d0eaa258702c5845983
[modules/med.git] / src / MEDMEM / MEDMEM_MedMeshDriver.cxx
1 #include "MEDMEM_MedMeshDriver.hxx"
2
3 #include "MEDMEM_DriversDef.hxx"
4
5 #include "MEDMEM_Family.hxx"
6 #include "MEDMEM_Group.hxx"
7 #include "MEDMEM_Coordinate.hxx"
8 #include "MEDMEM_Connectivity.hxx"
9 #include "MEDMEM_Mesh.hxx"
10 #include "MEDMEM_CellModel.hxx"
11
12 extern "C" {
13   extern med_idt _MEDdatagroupOuvrir(med_idt pid, char *nom);
14   extern med_err _MEDdatagroupFermer(med_idt id);
15 }
16 using namespace MED_FR;
17
18 // Every memory allocation made in the MedDriver members function are desallocated in the Mesh destructor 
19
20 void    MED_MESH_DRIVER::setMeshName(const string & meshName) { _meshName = meshName; };
21 string  MED_MESH_DRIVER::getMeshName() const { return _meshName; };
22
23 //---------------------------------- RDONLY PART -------------------------------------------------------------
24
25 //A FAIRE UTILISER LES MAPS...
26 const MED_FR::med_geometrie_element  MED_MESH_DRIVER::all_cell_type[MED_NBR_GEOMETRIE_MAILLE]=
27   { MED_FR::MED_POINT1,MED_FR::MED_SEG2,MED_FR::MED_SEG3,MED_FR::MED_TRIA3,MED_FR::MED_QUAD4,MED_FR::MED_TRIA6,MED_FR::MED_QUAD8,
28     MED_FR::MED_TETRA4,MED_FR::MED_PYRA5,MED_FR::MED_PENTA6,MED_FR::MED_HEXA8,MED_FR::MED_TETRA10,MED_FR::MED_PYRA13,
29     MED_FR::MED_PENTA15, MED_FR::MED_HEXA20};
30
31 const char * const MED_MESH_DRIVER::all_cell_type_tab [MED_NBR_GEOMETRIE_MAILLE]=
32   { "MED_POINT1","MED_SEG2","MED_SEG3","MED_TRIA3","MED_QUAD4","MED_TRIA6","MED_QUAD8",
33     "MED_TETRA4","MED_PYRA5","MED_PENTA6","MED_HEXA8","MED_TETRA10","MED_PYRA13",
34     "MED_PENTA15","MED_HEXA20"};
35
36
37
38
39 void MED_MESH_RDONLY_DRIVER::read(void)
40 {
41   const char * LOC = "MED_MESH_RDONLY_DRIVER::read() : " ;
42   BEGIN_OF(LOC);
43   if (_status!=MED_OPENED)
44     throw MEDEXCEPTION(" ");
45     //throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The _idt of file " << _fileName << " is : " << _medIdt <<  " (the file is not opened)." )) ;
46
47   _ptrMesh->_name =  _meshName;
48   
49   if (getCOORDINATE()!=MED_VALID)
50     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getCOORDINATE"  )) ;
51  
52   if (getCONNECTIVITY()!=MED_VALID)
53     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getCOONECTIVITY")) ;
54   
55   if (getFAMILY()!=MED_VALID)
56     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getFAMILY"      )) ;
57   
58   updateFamily();
59
60   // we build all groups
61   // on node
62   buildAllGroups(_ptrMesh->_groupNode,_ptrMesh->_familyNode) ;
63   _ptrMesh->_numberOfNodesGroups = _ptrMesh->_groupNode.size() ;
64   // on cell
65   buildAllGroups(_ptrMesh->_groupCell,_ptrMesh->_familyCell) ;
66   _ptrMesh->_numberOfCellsGroups = _ptrMesh->_groupCell.size() ;
67   // on face
68   buildAllGroups(_ptrMesh->_groupFace,_ptrMesh->_familyFace) ;
69   _ptrMesh->_numberOfFacesGroups = _ptrMesh->_groupFace.size() ;
70   // on edge
71   buildAllGroups(_ptrMesh->_groupEdge,_ptrMesh->_familyEdge) ;
72   _ptrMesh->_numberOfEdgesGroups = _ptrMesh->_groupEdge.size() ;
73
74   END_OF(LOC);
75 }
76
77
78 // A FAIRE : RENVOYER DU VOID
79 int  MED_MESH_RDONLY_DRIVER::getCOORDINATE()
80 {
81   const char * LOC = "MED_MESH_RDONLY_DRIVER::getCOORDINATE() : " ;
82   BEGIN_OF(LOC);
83
84   if (_status==MED_OPENED)
85     {
86       int err ;
87       
88       // Read the dimension of the space for the mesh <_meshName>
89       // to be able to create a COORDINATE object
90       int SpaceDimension = MEDdimLire(_medIdt,const_cast <char *> (_meshName.c_str())) ;
91       if ( SpaceDimension  <= MED_VALID ) 
92         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"The space dimension |" << SpaceDimension << "| seems to be incorrect "
93                                      << "for the mesh : |" << _meshName << "|")) ;
94       _ptrMesh->_spaceDimension = SpaceDimension ;
95
96       
97
98       // Read the number of nodes used in the mesh <_meshName>
99       // to be able to create a COORDINATE object
100       int NumberOfNodes=MEDnEntMaa(_medIdt,
101                                    const_cast <char *> (_meshName.c_str()),
102                                    MED_FR::MED_COOR,
103                                    MED_FR::MED_NOEUD,
104                                    (MED_FR::med_geometrie_element) MED_NONE,
105                                    (MED_FR::med_connectivite)      MED_NONE);
106       if ( NumberOfNodes <= MED_VALID )
107         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"The number of nodes |" << NumberOfNodes << "| seems to be incorrect "
108                                      << "for the mesh : |" << _meshName << "|" )) ;
109       _ptrMesh->_numberOfNodes = NumberOfNodes ;
110
111
112
113       // create a COORDINATE object
114       _ptrMesh->_coordinate = new COORDINATE(MED_EN::MED_FULL_INTERLACE, SpaceDimension, NumberOfNodes);
115       
116       MED_FR::med_repere rep ; // ATTENTION ---> DOIT ETRE INTEGRE DS MESH EF: FAIT NON?
117       string tmp_nom_coord (MED_TAILLE_PNOM*(_ptrMesh->_spaceDimension)+1,'\0');
118       string tmp_unit_coord(MED_TAILLE_PNOM*(_ptrMesh->_spaceDimension)+1,'\0');
119       char * tmp_nom = (const_cast <char *> ( tmp_nom_coord.c_str())  ) ;
120       char * tmp_unit= (const_cast <char *> ( tmp_unit_coord.c_str()) ) ;
121
122       err=MEDcoordLire(_medIdt,
123                        const_cast <char *> (_ptrMesh->_name.c_str()),
124                        _ptrMesh->_spaceDimension,
125                        const_cast <double *> ( _ptrMesh->_coordinate->_coordinate->get(MED_EN::MED_FULL_INTERLACE) ),
126                        MED_FR::MED_FULL_INTERLACE,
127                        MED_ALL,                      // we read all the coordinates
128                        NULL,                         // we don't use a profile
129                        0,                            // so the profile's size is 0
130                        &rep,tmp_nom,tmp_unit);
131       if (err != MED_VALID)
132         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't read coordinates of the |" << NumberOfNodes << "| nodes "
133                                      << "for the mesh : |" << _meshName 
134                                      << "| of space dimension |" << SpaceDimension 
135                                      << "| with units names |"   << tmp_nom
136                                      << "| and units |"          << tmp_unit
137                                      << " |")) ;
138       
139       for (int i=0;i<_ptrMesh->_spaceDimension;i++) {
140         // PG : What about blank !!!!!
141         _ptrMesh->_coordinate->_coordinateName[i]=string(tmp_nom,i*MED_TAILLE_PNOM,MED_TAILLE_PNOM) ;
142         _ptrMesh->_coordinate->_coordinateUnit[i]=string(tmp_unit,i*MED_TAILLE_PNOM,MED_TAILLE_PNOM);
143       }
144
145       // Pourquoi le stocker sous forme de chaîne ?
146       switch (rep)
147         {
148         case MED_FR::MED_CART : 
149           {
150             _ptrMesh->_coordinate->_coordinateSystem = "CARTESIAN";
151             break ;
152           }
153         case MED_FR::MED_CYL :
154           {
155             _ptrMesh->_coordinate->_coordinateSystem = "CYLINDRICAL";
156             break ;
157           }
158         case MED_FR::MED_SPHER :
159           {
160             _ptrMesh->_coordinate->_coordinateSystem = "SPHERICAL";
161             break ;
162           }
163         default :
164           {
165             _ptrMesh->_coordinate->_coordinateSystem = "UNDEFINED"; // ?Erreur ?
166             break ;
167           }
168         }
169
170       // Read the unused optionnal node Names
171       char * tmp_node_name = new char[NumberOfNodes*MED_TAILLE_PNOM+1];
172       tmp_node_name[NumberOfNodes]='\0' ;
173       err=MEDnomLire(_medIdt,const_cast <char*> (_ptrMesh->_name.c_str()),
174                      tmp_node_name,NumberOfNodes*MED_TAILLE_PNOM,MED_FR::MED_NOEUD,
175                      (MED_FR::med_geometrie_element) MED_NONE);
176       if (err == MED_VALID) 
177         INFOS(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : WARNING : Nodes have names but we do not read them !");
178       delete[] tmp_node_name ;
179
180
181       // ??? Read the unused optionnal node Numbers ???
182       int * tmp_node_number = new int[NumberOfNodes] ;
183       err=MEDnumLire(_medIdt,const_cast <char*> (_ptrMesh->_name.c_str()),
184                      tmp_node_number,NumberOfNodes,MED_NOEUD,(MED_FR::med_geometrie_element)0);
185       if (err == MED_VALID) {
186         INFOS(LOC<<"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING");
187         INFOS(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : WARNING : Nodes have numbers but we do not take care of them !");
188         INFOS(LOC<<"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING");
189         _ptrMesh->_coordinate->_nodeNumber = tmp_node_number ;
190       } else
191         delete[] tmp_node_number ;
192       
193       END_OF(LOC);
194       return MED_VALID;
195     }
196   return MED_ERROR;
197 }
198
199
200 int MED_MESH_RDONLY_DRIVER::getCONNECTIVITY() 
201 {
202   const char * LOC = "MED_MESH_RDONLY_DRIVER::getCONNECTIVITY : " ;
203   BEGIN_OF(LOC);
204
205   if (_status==MED_OPENED)
206     {
207
208       int err = 0 ;
209       // read MED_CELL connectivity
210       CONNECTIVITY * Connectivity     = new CONNECTIVITY(MED_CELL) ;
211       Connectivity->_numberOfNodes    = _ptrMesh->_numberOfNodes ;   // EF : Pourquoi cet attribut est-il dans MESH et non dans COORDINATE ?
212
213       // Try to read nodal connectivity of the cells <Connectivity->_nodal>
214       // then try to read descending connectivity    <Connectivity->_descending>
215       // if neither nodal nor descending connectivity exists
216       // throw an exception.
217       err = getNodalConnectivity(Connectivity) ;
218       if (err!=MED_VALID) {
219         Connectivity->_typeConnectivity = MED_DESCENDING ;
220         err = getDescendingConnectivity(Connectivity) ;
221       } else 
222         getDescendingConnectivity(Connectivity) ; // we read it if there is one
223       
224       if (err!=MED_VALID) {
225         delete Connectivity ;
226         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "We could not read any Connectivity")) ;
227       }
228
229       _ptrMesh->_meshDimension = Connectivity->_entityDimension ; 
230
231       // At this point Connectivity->_typeConnectivity is either NODAL or DESCENDING
232       // If both connectivities are found Connectivity->_typeConnectivity is NODAL
233       // If space dimension is 3 
234       // try to read the nodal connectivity of the faces <ConnectivityFace->_nodal> then
235       // try to read the descending connectivity <ConnectivityFace->_descending>
236       // if there is no descending connectivity and the CELLS are
237       // defined in descending mode then throw an exception
238
239       // PROVISOIRE : if we have some face or edge in MED_MAILLE, we don't read more. There could not be have face or edge !!!!
240
241       if(Connectivity->_constituent==NULL) {
242
243       SCRUTE(_ptrMesh->_meshDimension);
244       if (_ptrMesh->_meshDimension == 3) {
245         MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DES FACES..." );
246         CONNECTIVITY * ConnectivityFace = new CONNECTIVITY(MED_EN::MED_FACE) ;
247         ConnectivityFace->_typeConnectivity = Connectivity->_typeConnectivity ; // NODAL or DESCENDING
248         SCRUTE(ConnectivityFace->_typeConnectivity);
249         if (Connectivity->_typeConnectivity == MED_DESCENDING) {
250           MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DESCENDANTE DES FACES" );
251           err = getDescendingConnectivity(ConnectivityFace) ;
252           if (err!=MED_VALID)
253             throw MEDEXCEPTION ( LOCALIZED(STRING(LOC) << "No FACE in descending connectivity")) ;
254           getNodalConnectivity(ConnectivityFace) ; // if any !
255         } else {
256           MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE NODALE DES FACES" );
257           err = getNodalConnectivity(ConnectivityFace) ;
258           if (err!=MED_VALID) { // or error ????? we are in NODAL mode.
259             err = getDescendingConnectivity(ConnectivityFace) ;
260           } else
261             getDescendingConnectivity(ConnectivityFace); // if any !
262         }
263         if (err!=MED_VALID) {
264           delete ConnectivityFace ;
265           MESSAGE(LOC<<"No FACE defined.") ;
266         } else {
267           MESSAGE(LOC<<" SAUVEGARDE DE LA CONNECTIVITE DES FACES DANS L'OBJET CONNECTIVITY" );
268           Connectivity->_constituent=ConnectivityFace ; 
269         }
270       }
271       
272       // read MED_EDGE connectivity
273       if (_ptrMesh->_meshDimension > 1) { // we are in 3 or 2D 
274         MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DES ARRETES...." );
275         CONNECTIVITY * ConnectivityEdge = new CONNECTIVITY(MED_EDGE) ;
276         ConnectivityEdge->_typeConnectivity = Connectivity->_typeConnectivity ;
277         if (Connectivity->_typeConnectivity == MED_DESCENDING) {
278           MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DESCENDANTE DES ARRETES" );
279           err = getDescendingConnectivity(ConnectivityEdge) ;
280           if (err!=MED_VALID)
281             throw MEDEXCEPTION ( LOCALIZED(STRING(LOC) << "No EDGE in descending connectivity")) ;
282           getNodalConnectivity(ConnectivityEdge) ; // if any !
283         } else {
284           MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE NODALE DES ARRETES" );
285           err = getNodalConnectivity(ConnectivityEdge) ;
286           if (err!=MED_VALID) { // or error ????? we are in NODAL mode.
287             err = getDescendingConnectivity(ConnectivityEdge) ;
288           } else
289             getDescendingConnectivity(ConnectivityEdge) ; // if any !
290         }
291         if (err!=MED_VALID) {
292           delete ConnectivityEdge ;
293           MESSAGE(LOC<<"No EDGE defined.") ;
294         } else {
295           if (_ptrMesh->_meshDimension == 3)
296             if (Connectivity->_constituent != NULL)
297               Connectivity->_constituent->_constituent=ConnectivityEdge ;
298             else
299               throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<< "EDGE defined but there are no FACE !")) ;
300           else { // IN 2D
301             MESSAGE(LOC<<" SAUVEGARDE DE LA CONNECTIVITE DES ARETES DANS L'OBJET CONNECTIVITY" );
302             Connectivity->_constituent=ConnectivityEdge ;
303           }
304         }
305       }
306       }
307       _ptrMesh->_connectivity  = Connectivity ;                                      
308
309       // all right !
310
311       // we have read all connectivity in file, now we must build descending connectivity if necessary !
312
313       // If connectivity descending is defined, we have nothing to do, all constituent are defined !
314       // If connectivity is only nodal, we must rebuild descending if we have some contituent !
315
316       //A FAIRE !!!!
317 //        if (Connectivity->_descending == NULL)
318 //      if (Connectivity->_constituent != NULL){
319 //        // update Connectivity->_constituent
320 //        CONNECTIVITY * myConstituentOld = Connectivity->_constituent ;
321 //        Connectivity->_constituent = (CONNECTIVITY *)NULL ;
322 //        Connectivity->calculateDescendingConnectivity() ;
323           
324 //      }
325       
326       END_OF(LOC);
327       return MED_VALID;
328     }
329   return MED_ERROR;
330 }
331
332 int MED_MESH_RDONLY_DRIVER::getNodalConnectivity(CONNECTIVITY * Connectivity) 
333 {
334   const char * LOC = "MED_MESH_RDONLY_DRIVER::getNodalConnectivity : " ;
335   BEGIN_OF(LOC);
336   if (_status==MED_OPENED)
337     {
338       // Get the type of entity to work on (previously set in the Connectivity Object)
339       MED_FR::med_entite_maillage Entity = (MED_FR::med_entite_maillage) Connectivity->getEntity();
340
341       // Get the number of cells of each type & store it in <tmp_cells_count>.
342       int * tmp_cells_count = new int[MED_NBR_GEOMETRIE_MAILLE] ;
343       for (int i=1;i<MED_NBR_GEOMETRIE_MAILLE;i++) {                       // EF :ON SCANNE DES GEOMETRIES INUTILES, UTILISER LES MAPS
344         tmp_cells_count[i]=MEDnEntMaa(_medIdt,(const_cast <char *> (_ptrMesh->_name.c_str())),
345                                       MED_FR::MED_CONN,(MED_FR::med_entite_maillage) Entity,
346                                       all_cell_type[i],MED_FR::MED_NOD); 
347
348         // We suppose there is no cells used as faces, this is forbidden !!!
349
350         // Only in version 2.2.x of MED, but before, it's right :-(
351
352         if (tmp_cells_count[i]>0) { 
353           Connectivity->_entityDimension=all_cell_type[i]/100;  
354           Connectivity->_numberOfTypes++;
355         }
356       }
357       
358
359       // well if there is nothing, we quit !
360       if ( Connectivity->_numberOfTypes == 0 ) {
361         delete[] tmp_cells_count ;
362         return MED_ERROR ;
363       }
364
365       // if MED version < 2.2.x, we read only entity with dimention = Connectivity->_entityDimension. Lesser dimension are face or edge !
366
367       char version_med[10] ;
368       if ( MEDfichEntete(_medIdt,MED_FR::MED_VERSION,version_med) != 0 ){
369         // error : we suppose we have not a good med file !
370         delete[] tmp_cells_count ;
371         return MED_ERROR ;
372       }
373
374       // we get version number
375 //        string medVersion(version_med);
376 //        int firstNumber = 
377       int * tmp_edges_count = new int[MED_NBR_GEOMETRIE_MAILLE] ;
378       int numberOfEdgesTypes = 0;
379       int * tmp_faces_count = new int[MED_NBR_GEOMETRIE_MAILLE] ;
380       int numberOfFacesTypes = 0;
381       if ((version_med != "2.2")&(Entity==MED_MAILLE)) {
382         Connectivity->_numberOfTypes=0;
383         for (int i=1;i<MED_NBR_GEOMETRIE_MAILLE;i++) {
384           tmp_faces_count[i]=0;
385           tmp_edges_count[i]=0;
386           if (tmp_cells_count[i]!=0) {
387             int dimension = all_cell_type[i]/100 ;
388             if (Connectivity->_entityDimension==dimension) 
389               Connectivity->_numberOfTypes++ ;
390             
391             if (dimension == 2)
392               if (Connectivity->_entityDimension==3) {
393                 tmp_faces_count[i]=tmp_cells_count[i] ;
394                 tmp_cells_count[i]=0 ;
395                 numberOfFacesTypes++;
396               }
397             if (dimension == 1)
398               if (Connectivity->_entityDimension>dimension) {
399                 tmp_edges_count[i]=tmp_cells_count[i] ;
400                 tmp_cells_count[i]=0;
401                 numberOfEdgesTypes++ ;
402               }
403           }
404         }
405       }
406
407       // bloc to read CELL :
408       {
409       // Prepare an array of indexes on the different cell types to create a MEDSKYLINEARRAY
410       // We use <tmp_cells_count> to calculate <Connectivity->_count> then we release it
411         Connectivity->_geometricTypes = new MED_EN::medGeometryElement [Connectivity->_numberOfTypes]   ;  // Double emploi pour des raisons pratiques 
412         Connectivity->_type           = new CELLMODEL                  [Connectivity->_numberOfTypes]   ;  //
413         Connectivity->_count          = new int                        [Connectivity->_numberOfTypes+1] ;
414         Connectivity->_count[0]       = 1;
415         
416         int size = 0 ; 
417         int TypeNumber=1 ;
418         for (int i=1;i<MED_NBR_GEOMETRIE_MAILLE;i++)  { // no point1 cell type (?)
419           if (tmp_cells_count[i]>0) {
420             
421             Connectivity->_count[TypeNumber]=Connectivity->_count[TypeNumber-1]+tmp_cells_count[i];
422             
423             CELLMODEL t( (MED_EN::medGeometryElement) MED_MESH_DRIVER::all_cell_type[i]) ;
424             Connectivity->_type[TypeNumber-1]=t ;
425             
426             Connectivity->_geometricTypes[TypeNumber-1]=( MED_EN::medGeometryElement) MED_MESH_DRIVER::all_cell_type[i] ;
427             
428             // probleme avec les mailles de dimension < a dimension du maillage :
429             // Il faut oter le zero a la lecture est le remettre a l'ecriture : ce n'est pas fait !!!!! On interdit ce cas pour l'instant !!!
430
431               
432             size+=tmp_cells_count[i]*((MED_MESH_DRIVER::all_cell_type[i])%100) ;
433             
434             MESSAGE(LOC
435                     << Connectivity->_count[TypeNumber]-1 << " cells of type " 
436                     << all_cell_type_tab[i] ); 
437             TypeNumber++;
438           }
439         }
440         
441         // Creation of the MEDSKYLINEARRAY
442         Connectivity->_nodal = new MEDSKYLINEARRAY(Connectivity->_count[Connectivity->_numberOfTypes]-1,size) ; 
443         int * NodalIndex = Connectivity->_nodal->getIndex() ;
444         NodalIndex[0]=1 ;
445         
446         // Fill the MEDSKYLINEARRAY by reading the MED file.
447         for (int i=0;i<Connectivity->_numberOfTypes;i++) {
448           int multi = 0 ;
449           MED_FR::med_geometrie_element med_type = (MED_FR::med_geometrie_element) Connectivity->_type[i].getType() ;
450 //        if ( Connectivity->_type[i].getDimension() < Connectivity->_entityDimension) 
451           if (Connectivity->_entity == MED_CELL)
452             if ( Connectivity->_type[i].getDimension() < _ptrMesh->_spaceDimension) 
453               multi=1;
454           
455           //      int NumberOfCell = Connectivity->_count[i+1]-Connectivity->_count[i] ;
456           int NumberOfNodeByCell = Connectivity->_type[i].getNumberOfNodes() ;
457           
458           // initialise index
459           for (int j=Connectivity->_count[i]; j<Connectivity->_count[i+1];j++)
460             NodalIndex[j]=NodalIndex[j-1]+NumberOfNodeByCell ; 
461
462           int tmp_numberOfCells = Connectivity->_count[i+1]-Connectivity->_count[i] ;
463           int * tmp_ConnectivityArray = new int[(NumberOfNodeByCell+multi)*tmp_numberOfCells];
464           
465 //        int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()),
466 //                            Connectivity->_entityDimension,tmp_ConnectivityArray,
467 //                            MED_FR::MED_FULL_INTERLACE,NULL,0,Entity,med_type,MED_FR::MED_NOD);
468           int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()),
469                               _ptrMesh->_spaceDimension,tmp_ConnectivityArray,
470                               MED_FR::MED_FULL_INTERLACE,NULL,0,Entity,med_type,MED_FR::MED_NOD);
471           if ( err != MED_VALID) {
472             delete[] tmp_ConnectivityArray;
473             delete[] tmp_cells_count;
474             delete[] tmp_faces_count;
475             delete[] tmp_edges_count;
476             MESSAGE(LOC<<": MEDconnLire returns "<<err) ;
477             return MED_ERROR ;
478           }
479           int * ConnectivityArray = Connectivity->_nodal->getI(Connectivity->_count[i]) ;
480           for (int j=0; j<tmp_numberOfCells; j++)
481             for (int k=0; k<NumberOfNodeByCell; k++) 
482               ConnectivityArray[j*NumberOfNodeByCell+k]=tmp_ConnectivityArray[j*(NumberOfNodeByCell+multi)+k] ;
483
484           delete[] tmp_ConnectivityArray;
485   
486         }
487       } // end of bloc to read CELL
488
489       delete[] tmp_cells_count; 
490
491       // get Face if any
492       // ===============
493
494       if (numberOfFacesTypes!=0) {
495         CONNECTIVITY * constituent = new CONNECTIVITY(numberOfFacesTypes,MED_EN::MED_FACE) ;
496         constituent->_entityDimension = 2 ;
497         constituent->_count[0]=1 ;
498
499         int size = 0 ; 
500         int size_more_one = 0 ; 
501         int TypeNumber=1 ;
502         for (int i=1;i<MED_NBR_GEOMETRIE_MAILLE;i++)  { // no point1 cell type (?)
503           if (tmp_faces_count[i]>0) {
504             
505             constituent->_count[TypeNumber]=constituent->_count[TypeNumber-1]+tmp_faces_count[i];
506             CELLMODEL t( (MED_EN::medGeometryElement) MED_MESH_DRIVER::all_cell_type[i]) ;
507             constituent->_type[TypeNumber-1]=t ;
508             
509             constituent->_geometricTypes[TypeNumber-1]=( MED_EN::medGeometryElement) MED_MESH_DRIVER::all_cell_type[i] ;
510             
511             size+=tmp_faces_count[i]*((MED_MESH_DRIVER::all_cell_type[i])%100) ;
512             TypeNumber++;
513           }
514         }
515         
516         // Creation of the MEDSKYLINEARRAY
517         constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1,size) ; 
518         int * NodalIndex = constituent->_nodal->getIndex() ;
519         NodalIndex[0]=1 ;
520         
521         // Fill the MEDSKYLINEARRAY by reading the MED file.
522         for (int i=0;i<constituent->_numberOfTypes;i++) {
523           MED_FR::med_geometrie_element med_type = (MED_FR::med_geometrie_element) constituent->_type[i].getType() ;
524
525           int NumberOfNodeByFace = constituent->_type[i].getNumberOfNodes() ;
526           
527           // initialise index
528           for (int j=constituent->_count[i]; j<constituent->_count[i+1];j++)
529             NodalIndex[j]=NodalIndex[j-1]+NumberOfNodeByFace ; 
530           
531           int tmp_numberOfFaces = constituent->_count[i+1]-constituent->_count[i] ;
532           // Il faut ajouter 1 pour le zero a la lecture !!!
533           int * tmp_constituentArray = new int[(NumberOfNodeByFace+1)*tmp_numberOfFaces] ;
534           
535           int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()),
536                               Connectivity->_entityDimension,tmp_constituentArray,
537                               MED_FR::MED_FULL_INTERLACE,NULL,0,MED_FR::MED_MAILLE,med_type,MED_FR::MED_NOD);
538           if ( err != MED_VALID) {
539             MESSAGE(LOC<<": MEDconnLire returns "<<err) ;
540             delete constituent ;
541             delete[] tmp_constituentArray;
542             delete[] tmp_faces_count;
543             delete[] tmp_edges_count;
544             return MED_ERROR ;
545           }
546
547           int * constituentArray = constituent->_nodal->getI(constituent->_count[i]) ;
548           for (int j=0; j<tmp_numberOfFaces; j++)
549             for (int k=0; k<NumberOfNodeByFace; k++)
550               constituentArray[j*NumberOfNodeByFace+k]=tmp_constituentArray[j*(NumberOfNodeByFace+1)+k] ;
551           
552           delete[] tmp_constituentArray;
553         }
554         
555         Connectivity->_constituent = constituent ;
556       }
557
558       delete[] tmp_faces_count;
559
560       // get Edge if any
561       // ===============
562       if (numberOfEdgesTypes!=0) {
563         CONNECTIVITY * constituent = new CONNECTIVITY(numberOfEdgesTypes,MED_EDGE) ;
564         constituent->_entityDimension = 2 ;
565         constituent->_count[0]=1 ;
566
567         int size = 0 ; 
568         int size_more_one = 0 ; 
569         int TypeNumber=1 ;
570         for (int i=1;i<MED_NBR_GEOMETRIE_MAILLE;i++)  { // no point1 cell type (?)
571           if (tmp_edges_count[i]>0) {
572             
573             constituent->_count[TypeNumber]=constituent->_count[TypeNumber-1]+tmp_edges_count[i];
574             CELLMODEL t( (MED_EN::medGeometryElement) MED_MESH_DRIVER::all_cell_type[i]) ;
575             constituent->_type[TypeNumber-1]=t ;
576             
577             constituent->_geometricTypes[TypeNumber-1]=( MED_EN::medGeometryElement) MED_MESH_DRIVER::all_cell_type[i] ;
578             
579             size+=tmp_edges_count[i]*((MED_MESH_DRIVER::all_cell_type[i])%100) ;
580             TypeNumber++;
581           }
582         }
583         
584         // Creation of the MEDSKYLINEARRAY
585         constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1,size) ; 
586         int * NodalIndex = constituent->_nodal->getIndex() ;
587         NodalIndex[0]=1 ;
588         
589         // Fill the MEDSKYLINEARRAY by reading the MED file.
590         for (int i=0;i<constituent->_numberOfTypes;i++) {
591           MED_FR::med_geometrie_element med_type = (MED_FR::med_geometrie_element) constituent->_type[i].getType() ;
592
593           int NumberOfNodeByEdge = constituent->_type[i].getNumberOfNodes() ;
594           
595           // initialise index
596           for (int j=constituent->_count[i]; j<constituent->_count[i+1];j++)
597             NodalIndex[j]=NodalIndex[j-1]+NumberOfNodeByEdge ; 
598           
599           int tmp_numberOfEdges = constituent->_count[i+1]-constituent->_count[i] ;
600           // Il faut ajouter 1 pour le zero a la lecture !!!
601           int * tmp_constituentArray = new int[(NumberOfNodeByEdge+1)*tmp_numberOfEdges] ;
602           
603           int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()),
604                               Connectivity->_entityDimension,tmp_constituentArray,
605                               MED_FR::MED_FULL_INTERLACE,NULL,0,MED_FR::MED_MAILLE,med_type,MED_FR::MED_NOD);
606           if ( err != MED_VALID) {
607             MESSAGE(LOC<<": MEDconnLire returns "<<err) ;
608             delete constituent ;
609             delete[] tmp_constituentArray;
610             delete[] tmp_edges_count;
611             return MED_ERROR ;
612           }
613
614           int * constituentArray = constituent->_nodal->getI(constituent->_count[i]) ;
615           for (int j=0; j<tmp_numberOfEdges; j++)
616             for (int k=0; k<NumberOfNodeByEdge; k++)
617               constituentArray[j*NumberOfNodeByEdge+k]=tmp_constituentArray[j*(NumberOfNodeByEdge+1)+k] ;
618           
619           delete[] tmp_constituentArray;
620         }
621
622         if (Connectivity->_entityDimension == 3) {
623           if (Connectivity->_constituent==NULL)
624             throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Edges are defined but there are no Faces !"));
625           Connectivity->_constituent->_constituent = constituent ;
626         } else 
627           Connectivity->_constituent = constituent ;
628       }
629
630       delete[] tmp_edges_count; 
631       
632       return MED_VALID;
633     }
634   return MED_ERROR;
635 }
636
637 int MED_MESH_RDONLY_DRIVER::getDescendingConnectivity(CONNECTIVITY * Connectivity) 
638 {
639   const char * LOC = "MED_MESH_RDONLY_DRIVER::getDescendingConnectivity " ;
640   if (_status==MED_OPENED)
641     {
642       MESSAGE(LOC<<" Not implemented !");
643     }
644   return MED_ERROR;
645 }
646
647 //  int  MED_MESH_RDONLY_DRIVER::getElementFamilies(CONNECTIVITY * Connectivity)
648 //  {
649 //    int err = 0 ;
650 //    int NumberOfTypes = Connectivity->_numberOfTypes ;
651 //    int * Count = Connectivity->_count ;
652 //    medGeometryElement * GeometricTypes= Connectivity->_geometricTypes ;
653 //    int ** tmp_array = new int*[NumberOfTypes] ;
654 //    for (int i=0; i<NumberOfTypes; i++) 
655 //      tmp_array[i]=NULL ;
656 //    for (int i=0; i<NumberOfTypes; i++) {
657 //      int NumberOfElements = Count[i+1]-Count[i] ;
658 //      int * tmp_families_number = new int[NumberOfElements] ;
659 //      err = MEDfamLire(_medIdt,const_cast <char*> (_ptrMesh->_name.c_str()),
660 //                   tmp_families_number,NumberOfElements,
661 //                   Connectivity->_entity,GeometricTypes[i]);
662 //      tmp_array[i]=tmp_families_number ;
663 //      if (err != MED_VALID) {
664 //        for (int j=0; j<NumberOfTypes; j++)
665 //      if (tmp_array[j] != NULL)
666 //        delete[] tmp_array[j] ;
667 //        delete[] tmp_array ;
668 //        throw MEDEXCEPTION("MED_MESH_RDONLY_DRIVER::getElementFamilies : No Family in element GeometricTypes[i]");
669 //      }
670 //    }
671   
672 //    if (Connectivity->_entity == MED_CELL)
673 //      _ptrMesh->_MEDArrayCellFamily = tmp_array ;
674 //    else if (Connectivity->_entity == MED_FACE)
675 //      _ptrMesh->_MEDArrayFaceFamily = tmp_array ;
676 //    else if (Connectivity->_entity == MED_EDGE)
677 //      _ptrMesh->_MEDArrayEdgeFamily = tmp_array ;
678   
679 //    return MED_VALID ;
680 //  }
681
682 int  MED_MESH_RDONLY_DRIVER::getFAMILY() 
683 {
684   const char * LOC = "MED_MESH_RDONLY_DRIVER::getFAMILY() : " ;
685   BEGIN_OF(LOC);
686
687   if (_status==MED_OPENED) {
688     int err = 0 ;
689     // read number :
690     // NODE :
691     err = getNodesFamiliesNumber() ; // error only if (_status!=MED_OPENED), other case exeception !
692     // CELL
693     _ptrMesh->_MEDArrayCellFamily = new (int*)[_ptrMesh->_connectivity->_numberOfTypes] ; // ET SI IL N'Y A PAS DE CELLS ?
694     getCellsFamiliesNumber(_ptrMesh->_MEDArrayCellFamily,_ptrMesh->_connectivity) ;
695     if (_ptrMesh->_connectivity->_constituent != NULL) {
696       if (_ptrMesh->_connectivity->_constituent->_entity == MED_EN::MED_FACE) {
697         // FACE
698         _ptrMesh->_MEDArrayFaceFamily = new (int*)[_ptrMesh->_connectivity->_constituent->_numberOfTypes] ;
699         getCellsFamiliesNumber(_ptrMesh->_MEDArrayFaceFamily,_ptrMesh->_connectivity->_constituent) ;
700       } else {
701         // EDGE in 2D
702         _ptrMesh->_MEDArrayEdgeFamily = new (int*)[_ptrMesh->_connectivity->_constituent->_numberOfTypes] ;
703         getCellsFamiliesNumber(_ptrMesh->_MEDArrayEdgeFamily,_ptrMesh->_connectivity->_constituent) ;
704       }
705       // EDGE in 3D
706       if (_ptrMesh->_connectivity->_constituent->_constituent != NULL) {
707         _ptrMesh->_MEDArrayEdgeFamily = new (int*)[_ptrMesh->_connectivity->_constituent->_constituent->_numberOfTypes] ;
708         getCellsFamiliesNumber(_ptrMesh->_MEDArrayEdgeFamily,_ptrMesh->_connectivity->_constituent) ; // we are in 3D !
709       }
710     }
711
712     // Creation of the families
713     int NumberOfFamilies = MEDnFam(_medIdt,const_cast <char *> (_meshName.c_str()),0,MED_FR::MED_FAMILLE) ;
714     if ( NumberOfFamilies < 1 ) // at least family 0 must exist 
715       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"There is no FAMILY, FAMILY 0 must exists" ));
716
717     vector<FAMILY*> &NodeFamilyVector = _ptrMesh->_familyNode ;
718     vector<FAMILY*> &CellFamilyVector = _ptrMesh->_familyCell ;
719     vector<FAMILY*> &FaceFamilyVector = _ptrMesh->_familyFace ;
720     vector<FAMILY*> &EdgeFamilyVector = _ptrMesh->_familyEdge ;
721
722     int numberOfNodesFamilies = 0 ;
723     int numberOfCellsFamilies = 0 ;
724     int numberOfFacesFamilies = 0 ;
725     int numberOfEdgesFamilies = 0 ;
726
727     for (int i=0;i<NumberOfFamilies;i++) {
728       
729       int NumberOfAttributes = MEDnFam(_medIdt,const_cast <char *> (_meshName.c_str()),i+1,MED_FR::MED_ATTR) ;
730       if (NumberOfAttributes < 0) 
731         throw MEDEXCEPTION("MED_MESH_RDONLY_DRIVER::getFAMILY() : NumberOfAttributes" );
732     
733       int NumberOfGroups = MEDnFam(_medIdt,const_cast <char *> (_meshName.c_str()),i+1,MED_FR::MED_GROUPE) ;
734       if (NumberOfGroups < 0)
735         throw MEDEXCEPTION("MED_MESH_RDONLY_DRIVER::getFAMILY() : NumberOfGroups" );
736       
737       int FamilyIdentifier ;
738       string FamilyName(MED_TAILLE_NOM,' ');
739       int *  AttributesIdentifier = new int[NumberOfAttributes] ;
740       int *  AttributesValues     = new int[NumberOfAttributes] ;
741       string AttributesDescription(MED_TAILLE_DESC*NumberOfAttributes,' ') ;
742       string GroupsNames(MED_TAILLE_LNOM*NumberOfGroups,' ') ;
743       err = MEDfamInfo(_medIdt,const_cast <char *> (_meshName.c_str()),
744                        i+1,const_cast <char *> (FamilyName.c_str()),
745                        &FamilyIdentifier,AttributesIdentifier,AttributesValues,
746                        const_cast <char *> (AttributesDescription.c_str()),
747                        &NumberOfAttributes,
748                        const_cast <char *> (GroupsNames.c_str()),&NumberOfGroups
749                        );
750       //SCRUTE(GroupsNames);
751       if (err != MED_VALID)
752         throw MEDEXCEPTION("MED_MESH_RDONLY_DRIVER::getFAMILY() : ERROR when get FAMILY informations" );
753       if (FamilyIdentifier != 0 ) {
754         FAMILY * Family = new FAMILY(_ptrMesh,FamilyIdentifier,FamilyName,
755                                      NumberOfAttributes,AttributesIdentifier,
756                                      AttributesValues,AttributesDescription,
757                                      NumberOfGroups,GroupsNames) ;
758         switch (Family->getEntity()) {
759         case MED_EN::MED_NODE :
760           NodeFamilyVector.push_back(Family) ;
761           numberOfNodesFamilies++ ;
762           break ;
763         case MED_EN::MED_CELL :
764           CellFamilyVector.push_back(Family) ;
765           numberOfCellsFamilies++ ;
766           break ;
767         case MED_EN::MED_FACE :
768           FaceFamilyVector.push_back(Family) ;
769           numberOfFacesFamilies++ ;
770           break ;
771         case MED_EN::MED_EDGE :
772           EdgeFamilyVector.push_back(Family) ;
773           numberOfEdgesFamilies++ ;
774           break ;
775         }
776       }
777     }
778     _ptrMesh->_numberOfNodesFamilies = numberOfNodesFamilies ;
779     _ptrMesh->_numberOfCellsFamilies = numberOfCellsFamilies ;
780     _ptrMesh->_numberOfFacesFamilies = numberOfFacesFamilies ;
781     _ptrMesh->_numberOfEdgesFamilies = numberOfEdgesFamilies ;
782     
783     END_OF(LOC);
784     return MED_VALID ;
785   }
786   return MED_ERROR;
787 }
788
789 int  MED_MESH_RDONLY_DRIVER::getNodesFamiliesNumber() 
790 {
791   const char * LOC = "MED_MESH_RDONLY_DRIVER::getNodesFamiliesNumber() : " ;
792   BEGIN_OF(LOC);
793   if (_status==MED_OPENED) {
794     int err = 0 ;
795     int * tmp_NodesFamilies = new int[_ptrMesh->getNumberOfNodes()] ;
796     err = MEDfamLire(_medIdt,(const_cast <char *> (_ptrMesh->_name.c_str())), 
797                      tmp_NodesFamilies, _ptrMesh->getNumberOfNodes(),
798                      MED_NOEUD,(enum MED_FR::med_geometrie_element) MED_NONE);
799     if ( err != MED_VALID) {
800       delete[] tmp_NodesFamilies ;
801       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "There is no family for the |"<< _ptrMesh->getNumberOfNodes() 
802                                    << "| nodes in mesh |" 
803                                    << _ptrMesh->_name.c_str() << "|" ));
804     }
805     _ptrMesh->_MEDArrayNodeFamily = tmp_NodesFamilies ;
806     END_OF(LOC);
807     return MED_VALID;
808   }
809   return MED_ERROR;
810 }
811
812 int  MED_MESH_RDONLY_DRIVER::getCellsFamiliesNumber(int **MEDArrayFamily,CONNECTIVITY *Connectivity) 
813 {
814   const char * LOC = "MED_MESH_RDONLY_DRIVER::getCellsFamiliesNumber " ;
815   BEGIN_OF(LOC);
816
817   if (_status==MED_OPENED) {
818     int i, err = 0 ;
819     for (i=0;i<Connectivity->_numberOfTypes;i++)        {
820       int NumberOfCell = Connectivity->_count[i+1]-Connectivity->_count[i] ;
821       int * fam = new int[NumberOfCell] ;
822
823       err=MEDfamLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()),
824                      fam,NumberOfCell,
825                      (MED_FR::med_entite_maillage) Connectivity->_entity,
826                      (MED_FR::med_geometrie_element) Connectivity->_geometricTypes[i]);
827
828       // provisoire : si les faces ou les aretes sont des mailles !!!
829       if (err != MED_VALID) {
830         MESSAGE(LOC<<"search face/edge family on cell !!!");
831         err=MEDfamLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()),
832                        fam,NumberOfCell,
833                        MED_FR::MED_MAILLE,
834                        (MED_FR::med_geometrie_element) Connectivity->_geometricTypes[i]);
835       }
836
837       MEDArrayFamily[i]=fam ;
838       if (err != MED_VALID) 
839         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Family not found for entity "<<Connectivity->_entity<<" and geometric type "<<Connectivity->_geometricTypes[i]));
840       
841     }
842     return MED_VALID;
843   }
844   return MED_ERROR;  
845 }
846
847 void MED_MESH_RDONLY_DRIVER::buildAllGroups(vector<GROUP*> & Groups, vector<FAMILY*> & Families) 
848 {
849   const char * LOC = "MED_MESH_RDONLY_DRIVER::buildAllGroups " ;
850   BEGIN_OF(LOC);
851
852   int numberOfFamilies = Families.size() ;
853   //SCRUTE(numberOfFamilies);
854   map< string,list<FAMILY*> > groupsNames ;
855   for(int i=0; i<numberOfFamilies; i++) {
856     FAMILY * myFamily = Families[i] ;
857     int numberOfGroups_ = myFamily->getNumberOfGroups();
858     //SCRUTE(i);
859     //SCRUTE(numberOfGroups_);
860     for (int j=0; j<numberOfGroups_; j++) {
861       //SCRUTE(j);
862       //SCRUTE(myFamily->getGroupName(j+1));
863       groupsNames[myFamily->getGroupName(j+1)].push_back(myFamily);
864     }
865   }
866   int numberOfGroups = groupsNames.size() ;
867   SCRUTE(numberOfGroups);
868   Groups.resize(numberOfGroups);
869   map< string,list<FAMILY*> >::const_iterator currentGroup ;
870   int it = 0 ;
871   for(currentGroup=groupsNames.begin();currentGroup!=groupsNames.end();currentGroup++) {
872     //    GROUP * myGroup = new GROUP((*currentGroup).first,(*currentGroup).second) ;
873     GROUP * myGroup = new GROUP() ;
874     myGroup->setName((*currentGroup).first);
875     SCRUTE(myGroup->getName());
876     //myGroup->setMesh(_ptrMesh);
877     myGroup->init((*currentGroup).second);
878     Groups[it]=myGroup;
879     //SCRUTE(it);
880     it++;
881   }
882
883   END_OF(LOC);
884 }
885
886 void MED_MESH_RDONLY_DRIVER::updateFamily()
887 {
888   const char * LOC = "MED_MESH_RDONLY_DRIVER::updateFamily() " ;
889   BEGIN_OF(LOC);
890
891   // we need to update family on constituent if we have constituent, but no 
892   // descending connectivity, so, we must calculate all constituent and
893   // numbering correctly family !
894   _ptrMesh->_connectivity->updateFamily(_ptrMesh->_familyFace) ; // in 2d, do nothing
895   _ptrMesh->_connectivity->updateFamily(_ptrMesh->_familyEdge) ; // in 3d, do nothing
896
897   END_OF(LOC);
898 }
899
900
901 void MED_MESH_RDONLY_DRIVER::write( void ) const { INFOS("MED_MESH_RDONLY_DRIVER::write : Can't write with a RDONLY driver !");}
902
903 /*--------------------- RDWR PART -------------------------------*/
904
905 void MED_MESH_RDWR_DRIVER::write(void) const { MED_MESH_WRONLY_DRIVER::write(); } 
906 void MED_MESH_RDWR_DRIVER::read (void)       { MED_MESH_RDONLY_DRIVER::read(); } 
907
908
909 /*--------------------- WRONLY PART -------------------------------*/
910 void MED_MESH_WRONLY_DRIVER::read (void)       {   INFOS("MED_MESH_WRONLY_DRIVER::write : Can't read with a WRONLY driver !");} 
911
912 void MED_MESH_WRONLY_DRIVER::write(void) const { 
913   const char * LOC = "void MED_MESH_WRONLY_DRIVER::write(void) const : ";
914   BEGIN_OF(LOC);
915
916   // we must first create mesh !!
917   MESSAGE(LOC<< "MeshName : "<< _meshName <<"FileName : "<<_fileName<<" MedIdt : "<< _medIdt);
918
919   if (writeCoordinates()!=MED_VALID)
920     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeCoordinates()"  )) ;
921
922   if (writeConnectivities(MED_EN::MED_CELL)!=MED_VALID)
923     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeConnectivities(MED_CELL)"  )) ;
924   if (writeConnectivities(MED_EN::MED_FACE)!=MED_VALID)
925     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeConnectivities(MED_FACE)"  )) ;
926   if (writeConnectivities(MED_EN::MED_EDGE)!=MED_VALID)
927     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeConnectivities(MED_EDGE)"  )) ;
928
929   if (writeFamilyNumbers() !=MED_VALID)
930     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilyNumbers()"  )) ;
931  
932   // well we must first write zero family :
933   if (_status==MED_OPENED) {
934     int err ;
935     // test if the family already exists (HDF trick waiting a MED evolution to be replaced)
936     string dataGroupFam = "/ENS_MAA/"+_meshName+"/FAS/FAMILLE_0/";  
937     SCRUTE("|"<<dataGroupFam<<"|");
938     if ( err =_MEDdatagroupOuvrir(_medIdt,const_cast <char *> (dataGroupFam.c_str()) ) < MED_VALID ) {
939       SCRUTE(err);
940       
941       err = MEDfamCr( _medIdt, const_cast <char *> ( _meshName.c_str() ),
942                       "FAMILLE_0", 0,
943                       (int*)NULL, (int*)NULL, (char*)NULL, 0,
944                       (char*)NULL, 0);
945       
946       if ( err != MED_VALID) 
947         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't create family |FAMILLE_0| with identifier |0| groups names || and  attributes descriptions ||")) ;
948     }
949     else
950       _MEDdatagroupFermer(_medIdt);
951      
952   }
953
954   MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyNode)");
955   if (writeFamilies(_ptrMesh->_familyNode) !=MED_VALID)
956     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyNode)"  )) ;
957
958   MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyCell)");
959   if (writeFamilies(_ptrMesh->_familyCell) !=MED_VALID)
960     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyCell)"  )) ;
961
962   MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyFace)");
963   if (writeFamilies(_ptrMesh->_familyFace) !=MED_VALID)
964     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyFace)"  )) ;
965
966   MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyEdge)");
967   if (writeFamilies(_ptrMesh->_familyEdge) !=MED_VALID)
968     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyEdge)"  )) ;
969
970   END_OF(LOC);
971
972
973
974 int MED_MESH_WRONLY_DRIVER::writeCoordinates() const {
975  
976   const char * LOC = "int MED_MESH_WRONLY_DRIVER::writeCoordinates() const : ";
977   BEGIN_OF(LOC);
978   if (_status==MED_OPENED) {
979
980     MED_FR::med_err err = MED_ERROR;
981     MED_FR::med_repere rep;
982     string tmp_name,tmp_unit;
983     
984     // Recompose the <_spaceDimension> strings in 1 string 
985     for (int i=0;i<_ptrMesh->_spaceDimension;i++) {
986       tmp_name += _ptrMesh->_coordinate->_coordinateName[i]; 
987       tmp_unit += _ptrMesh->_coordinate->_coordinateUnit[i]; 
988
989     }
990
991     // Test if the mesh <_meshName> already exists
992     // If it doesn't exists create it
993     // If it already exists verify if its dimension is the same as <_ptrMesh->_spaceDimension>
994     // rem : <_meshName> is the driver meshName not <ptrMesh->_meshName>
995     int dim = MEDdimLire(_medIdt, const_cast <char *> (_meshName.c_str()) );
996     if (dim < MED_VALID) 
997       if (MEDmaaCr(_medIdt,const_cast <char *> (_meshName.c_str()),_ptrMesh->_spaceDimension) != 0 )
998         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Unable to create Mesh"));
999       else 
1000         {
1001           MESSAGE(LOC<<"Mesh "<<_meshName<<" created in file "<<_fileName<<" !");
1002         }
1003     else if (dim != _ptrMesh->_spaceDimension) 
1004       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Mesh |" << _meshName.c_str() << "| already exists in file |" << _fileName
1005                                    << "| with dimension |" << dim << "| but the dimension of the mesh we want to write is |"
1006                                    << _ptrMesh->_spaceDimension <<"|" )) ;
1007     
1008     // Pourquoi le stocker sous forme de chaîne ?
1009     const string & coordinateSystem = _ptrMesh->_coordinate->_coordinateSystem;
1010     if      (coordinateSystem  == "CARTESIAN") 
1011       rep = MED_FR::MED_CART;
1012     else if ( coordinateSystem == "CYLINDRICAL")
1013       rep = MED_FR::MED_CYL;
1014     else if ( coordinateSystem == "SPHERICAL" )
1015       rep = MED_FR::MED_SPHER;
1016     else
1017       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Mesh |" << _meshName.c_str() << "| doesn't have a valid coordinate system : |" 
1018                                    << _ptrMesh->_coordinate->_coordinateSystem
1019                                    << "|" )) ;  
1020       
1021     err = MEDcoordEcr(_medIdt, const_cast <char *> (_meshName.c_str()),
1022                       _ptrMesh->_spaceDimension, 
1023                       const_cast <double *> ( _ptrMesh->_coordinate->_coordinate->get(MED_EN::MED_FULL_INTERLACE) ), 
1024                       MED_FR::MED_FULL_INTERLACE, 
1025                       _ptrMesh->_numberOfNodes,                 //  _ptrMesh->_coordinate->_numberOfNodes
1026                       MED_FR::MED_REMP,    
1027                       rep,
1028                       const_cast <char *> (tmp_name.c_str()), 
1029                       const_cast <char *> (tmp_unit.c_str()) 
1030                       );  
1031
1032     if (err<0) 
1033       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write coordinates of mesh |" << _meshName.c_str() << "| in file |" << _fileName
1034                                    << "| with dimension |"  << _ptrMesh->_spaceDimension <<"| and" 
1035                                    << " with units names |"  << tmp_name
1036                                    << "| and units |"       << tmp_unit
1037                                    << " |")) ;    
1038     
1039     END_OF(LOC);
1040     
1041     return MED_VALID;
1042   }
1043
1044   MESSAGE (LOC<<" Not open !!!");
1045   return MED_ERROR;
1046 }
1047
1048
1049
1050
1051 int MED_MESH_WRONLY_DRIVER::writeConnectivities(medEntityMesh entity) const {
1052   
1053   const char * LOC="int MED_MESH_WRONLY_DRIVER::writeConnectivities() const : ";
1054   BEGIN_OF(LOC);
1055
1056   MED_FR::med_err err;
1057   
1058   if (_status==MED_OPENED) {
1059     
1060     // REM SI LA METHODE EST APPELEE DIRECTEMENT ET QUE LE MAILLAGE N'EST PAS CREE IL Y A PB !
1061     
1062     // A FAIRE : A tester surtout dans les methodes de MESH.
1063     //    if ( _ptrMesh->_connectivity == (CONNECTIVITY *) MED_INVALID )
1064     if ( _ptrMesh->_connectivity == (CONNECTIVITY *) NULL )
1065       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The connectivity is not defined in the MESH object ")) ;
1066     
1067     if   ( _ptrMesh->existConnectivity(MED_NODAL,entity) ) { 
1068
1069       int numberOfTypes           = _ptrMesh->getNumberOfTypes (entity) ;
1070       medGeometryElement  * types = _ptrMesh->getTypes         (entity) ;
1071     
1072       for (int i=0; i<numberOfTypes; i++) {
1073       
1074         int    numberOfElements = _ptrMesh->getNumberOfElements (entity,types[i]);
1075         int * connectivity      = _ptrMesh->getConnectivity     (MED_EN::MED_FULL_INTERLACE, 
1076                                                                  MED_NODAL, entity, types[i]); // ?? et SI MED_NODAL n'existe pas, recalcul auto ??
1077       
1078         // Pour l'instant la class utilise le multi.....
1079         int multi = 0 ;
1080         if (entity==MED_EN::MED_CELL)
1081           if ( (types[i]/ 100) < _ptrMesh->_spaceDimension) 
1082             multi=1 ;
1083         int numberOfNodes = types[i]%100 ;
1084         int * connectivityArray = new int[numberOfElements*(numberOfNodes+multi)];
1085         for (int j=0 ; j<numberOfElements; j++) {
1086           for (int k=0; k<numberOfNodes; k++)
1087             connectivityArray[j*(numberOfNodes+multi)+k]=connectivity[j*numberOfNodes+k] ;
1088           connectivityArray[j*(numberOfNodes+multi)+numberOfNodes]=0;
1089         }
1090         err = MEDconnEcr( _medIdt, const_cast <char *> ( _meshName.c_str()), _ptrMesh->_spaceDimension,
1091                           connectivityArray, MED_FR::MED_FULL_INTERLACE , numberOfElements,
1092                           MED_FR::MED_REMP,
1093                           (MED_FR::med_entite_maillage  ) entity, 
1094                           (MED_FR::med_geometrie_element) types[i], MED_NOD );
1095         delete[] connectivityArray ;
1096
1097         if (err<0) // ETENDRE LES EXPLICATIONS
1098           throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write connectivities of mesh |" << _meshName.c_str() << "| in file |" << _fileName
1099                                        << "| with dimension |"  << _ptrMesh->_spaceDimension <<"| and" 
1100                                        )) ;
1101       }
1102     }
1103     // Connctivity descending :
1104     if   ( _ptrMesh->existConnectivity(MED_DESCENDING,entity) ) { 
1105       
1106       int numberOfTypes           = _ptrMesh->getNumberOfTypes (entity) ;
1107       medGeometryElement  * types = _ptrMesh->getTypes         (entity) ;
1108       
1109       for (int i=0; i<numberOfTypes; i++) {
1110         
1111         int    numberOfElements = _ptrMesh->getNumberOfElements (entity,types[i]);
1112         int * connectivity = _ptrMesh->getConnectivity(MED_EN::MED_FULL_INTERLACE, MED_DESCENDING, entity, types[i]); 
1113       
1114         // Pour l'instant la class utilise le multi.....
1115         err = MEDconnEcr( _medIdt, const_cast <char *> ( _meshName.c_str()), _ptrMesh->_spaceDimension,
1116                           connectivity, MED_FR::MED_FULL_INTERLACE , numberOfElements,
1117                           MED_FR::MED_REMP,
1118                           (MED_FR::med_entite_maillage  ) entity, 
1119                           (MED_FR::med_geometrie_element) types[i], MED_DESC );
1120         
1121         if (err<0) // ETENDRE LES EXPLICATIONS
1122           throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write connectivities of mesh |" << _meshName.c_str() << "| in file |" << _fileName
1123                                        << "| with dimension |"  << _ptrMesh->_spaceDimension <<"| and" 
1124                                        )) ;
1125       }
1126     }
1127     // Connctivity descending :
1128     if   ( _ptrMesh->existConnectivity(MED_DESCENDING,entity) ) { 
1129       
1130       int numberOfTypes           = _ptrMesh->getNumberOfTypes (entity) ;
1131       medGeometryElement  * types = _ptrMesh->getTypes         (entity) ;
1132       
1133       for (int i=0; i<numberOfTypes; i++) {
1134         
1135         int    numberOfElements = _ptrMesh->getNumberOfElements (entity,types[i]);
1136         int * connectivity = _ptrMesh->getConnectivity(MED_EN::MED_FULL_INTERLACE, MED_DESCENDING, entity, types[i]); 
1137       
1138         // Pour l'instant la class utilise le multi.....
1139         err = MEDconnEcr( _medIdt, const_cast <char *> ( _meshName.c_str()), _ptrMesh->_spaceDimension,
1140                           connectivity, MED_FR::MED_FULL_INTERLACE , numberOfElements,
1141                           MED_FR::MED_REMP,
1142                           (MED_FR::med_entite_maillage  ) entity, 
1143                           (MED_FR::med_geometrie_element) types[i], MED_DESC );
1144         
1145         if (err<0) // ETENDRE LES EXPLICATIONS
1146           throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write connectivities of mesh |" << _meshName.c_str() << "| in file |" << _fileName
1147                                        << "| with dimension |"  << _ptrMesh->_spaceDimension <<"| and" 
1148                                        )) ;
1149             
1150       }
1151     }
1152     END_OF(LOC);
1153     return MED_VALID;
1154   }
1155   return MED_ERROR;
1156 }
1157
1158 int MED_MESH_WRONLY_DRIVER::writeFamilyNumbers() const {
1159   
1160   const char * LOC="int MED_MESH_WRONLY_DRIVER::writeFamilyNumbers() const : ";
1161   BEGIN_OF(LOC);
1162
1163   MED_FR::med_err err;
1164   
1165   if (_status==MED_OPENED) {
1166
1167     // SOLUTION TEMPORAIRE CAR _ptrMesh->_MEDArrayNodeFamily DOIT ETRE ENLEVER DE LA CLASSE MESH
1168     err = MEDfamEcr(_medIdt, const_cast <char *> ( _meshName.c_str() ),
1169                     _ptrMesh->_MEDArrayNodeFamily, _ptrMesh->getNumberOfNodes(),MED_FR::MED_REMP ,
1170                     MED_NOEUD,(enum MED_FR::med_geometrie_element) MED_NONE); 
1171     if ( err != MED_VALID) 
1172       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't write node family for the |"<< _ptrMesh->getNumberOfNodes() 
1173                                    << "| nodes in mesh |" 
1174                                    << _ptrMesh->_name.c_str() << "|" ));   
1175
1176
1177     { // CELLS RELATED BLOCK
1178       medEntityMesh entity=MED_EN::MED_CELL;
1179       // SOLUTION TEMPORAIRE CAR _ptrMesh->_MEDArray____Family DOIT ETRE ENLEVER DE LA CLASSE MESH
1180       if  ( ( _ptrMesh->existConnectivity(MED_NODAL,entity) )|( _ptrMesh->existConnectivity(MED_DESCENDING,entity) ) ) { 
1181
1182         int numberOfTypes           = _ptrMesh->getNumberOfTypes (entity) ;
1183         medGeometryElement  * types = _ptrMesh->getTypes         (entity) ;
1184       
1185         for (int i=0; i<numberOfTypes; i++) {
1186
1187           err = MEDfamEcr(_medIdt, const_cast <char *> ( _meshName.c_str() ),
1188                           _ptrMesh->_MEDArrayCellFamily[i], _ptrMesh->getNumberOfElements(entity, types[i]),
1189                           MED_FR::MED_REMP ,
1190                           (MED_FR::med_entite_maillage) entity,
1191                           (MED_FR::med_geometrie_element) types[i]); 
1192         
1193           if ( err != MED_VALID) 
1194             throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't write family for the |"<< _ptrMesh->getNumberOfElements(entity, types[i])
1195                                          << "| cells of geometric type |" << geoNames[ (MED_FR::med_geometrie_element) types[i]] <<"|in mesh |"      
1196                                          << _ptrMesh->_name.c_str() << "|" ));   
1197         }
1198       }
1199     }
1200
1201     { // FACE RELATED BLOCK
1202       medEntityMesh entity=MED_EN::MED_FACE;
1203       // SOLUTION TEMPORAIRE CAR _ptrMesh->_MEDArray____Family DOIT ETRE ENLEVER DE LA CLASSE MESH
1204       if  ( ( _ptrMesh->existConnectivity(MED_NODAL,entity) )|( _ptrMesh->existConnectivity(MED_DESCENDING,entity) ) ) { 
1205
1206         int numberOfTypes           = _ptrMesh->getNumberOfTypes (entity) ;
1207         medGeometryElement  * types = _ptrMesh->getTypes         (entity) ;
1208       
1209         int numberOfElements = _ptrMesh->getNumberOfElements(entity, MED_ALL_ELEMENTS) ;
1210         int * familyArray = new int[numberOfElements] ;
1211         for (int i=0;i<numberOfElements;i++)
1212           familyArray[i]=0;
1213
1214         int numberOfFamilies = _ptrMesh->getNumberOfFamilies(entity) ;
1215         vector<FAMILY*> myFamilies = _ptrMesh->getFamilies(entity) ;
1216         for (int i=0;i<numberOfFamilies;i++) {
1217           int familyNumber = myFamilies[i]->getIdentifier() ;
1218           int numberOfFamilyElements = myFamilies[i]->getNumberOfElements(MED_ALL_ELEMENTS) ;
1219           int * myFamilyElements = myFamilies[i]->getNumber(MED_ALL_ELEMENTS) ;
1220           for (int ii=0;ii<numberOfFamilyElements;ii++)
1221               familyArray[myFamilyElements[ii]-1]=familyNumber;
1222         }
1223
1224         int * typeCount = _ptrMesh->getGlobalNumberingIndex(entity) ;
1225
1226         for (int i=0; i<numberOfTypes; i++) {
1227
1228           int typeNumberOfElements = typeCount[i+1] - typeCount[i] ;
1229           err = MEDfamEcr(_medIdt, const_cast <char *> ( _meshName.c_str() ),
1230                           familyArray+typeCount[i]-1, typeNumberOfElements,
1231                           MED_FR::MED_REMP ,
1232                           (MED_FR::med_entite_maillage) entity,
1233                           (MED_FR::med_geometrie_element) types[i]); 
1234
1235           if ( err != MED_VALID) 
1236             throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't write family for the |"<< _ptrMesh->getNumberOfElements(entity, types[i])
1237                                          << "| faces of geometric type |" << geoNames[ (MED_FR::med_geometrie_element) types[i]] <<"|in mesh |"      
1238                                          << _ptrMesh->_name.c_str() << "|" ));   
1239         }
1240         delete[] familyArray ;
1241       }
1242     }
1243
1244     { // EDGE RELATED BLOCK
1245       //medEntityMesh entity=MED_EN::MED_FACE;
1246       medEntityMesh entity=MED_EN::MED_EDGE;
1247       // SOLUTION TEMPORAIRE CAR _ptrMesh->_MEDArray____Family DOIT ETRE ENLEVER DE LA CLASSE MESH
1248       if  ( ( _ptrMesh->existConnectivity(MED_NODAL,entity) )|( _ptrMesh->existConnectivity(MED_DESCENDING,entity) ) ) { 
1249
1250         int numberOfTypes           = _ptrMesh->getNumberOfTypes (entity) ;
1251         medGeometryElement  * types = _ptrMesh->getTypes         (entity) ;
1252       
1253         int numberOfElements = _ptrMesh->getNumberOfElements(entity, MED_ALL_ELEMENTS) ;
1254         int * familyArray = new int[numberOfElements] ;
1255         for (int i=0;i<numberOfElements;i++)
1256           familyArray[i]=0;
1257
1258         int numberOfFamilies = _ptrMesh->getNumberOfFamilies(entity) ;
1259         vector<FAMILY*> myFamilies = _ptrMesh->getFamilies(entity) ;
1260         for (int i=0;i<numberOfFamilies;i++) {
1261           int familyNumber = myFamilies[i]->getIdentifier() ;
1262           int numberOfFamilyElements = myFamilies[i]->getNumberOfElements(MED_ALL_ELEMENTS) ;
1263           int * myFamilyElements = myFamilies[i]->getNumber(MED_ALL_ELEMENTS) ;
1264           for (int ii=0;ii<numberOfFamilyElements;ii++)
1265               familyArray[myFamilyElements[ii]-1]=familyNumber;
1266         }
1267
1268         int * typeCount = _ptrMesh->getGlobalNumberingIndex(entity) ;
1269
1270         for (int i=0; i<numberOfTypes; i++) {
1271
1272           int typeNumberOfElements = typeCount[i+1] - typeCount[i] ;
1273           err = MEDfamEcr(_medIdt, const_cast <char *> ( _meshName.c_str() ),
1274                           familyArray+typeCount[i]-1, typeNumberOfElements,
1275                           MED_FR::MED_REMP ,
1276                           (MED_FR::med_entite_maillage) entity,
1277                           (MED_FR::med_geometrie_element) types[i]); 
1278         
1279           if ( err != MED_VALID) 
1280             throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't write family for the |"<< _ptrMesh->getNumberOfElements(entity, types[i])
1281                                          << "| edges of geometric type |" << geoNames[ (MED_FR::med_geometrie_element) types[i]] <<"|in mesh |"      
1282                                          << _ptrMesh->_name.c_str() << "|" ));   
1283         }
1284       }
1285     }
1286     
1287     END_OF(LOC);
1288     return MED_VALID;
1289   }
1290   return MED_ERROR;
1291 }
1292
1293
1294 int MED_MESH_WRONLY_DRIVER::writeFamilies(vector<FAMILY*> & families ) const {
1295   
1296   const char * LOC="int MED_MESH_WRONLY_DRIVER::writeFamilies(vector<FAMILY*> families) const : ";
1297   BEGIN_OF(LOC);
1298
1299   MED_FR::med_err err;
1300   
1301   if (_status==MED_OPENED) {
1302
1303     MESSAGE(LOC<<" families.size() :"<<families.size());
1304
1305     for (int i=0; i< families.size(); i++) {
1306
1307       int      numberOfAttributes         = families[i]->getNumberOfAttributes ();
1308       string   attributesDescriptions     = "";
1309
1310       // Recompose the attributes descriptions arg for MED
1311       for (int j=0; j < numberOfAttributes; j++) {
1312         
1313         string attributeDescription = families[i]->getAttributeDescription(j+1);
1314         
1315         if ( attributeDescription.size() > MED_TAILLE_DESC )
1316           throw MEDEXCEPTION( LOCALIZED(STRING(LOC) << "The size of the attribute description n° |" << j+1 << "| of the family |" << families[i]->getName()
1317                                         << "| with identifier |" << families[i]->getIdentifier()  << "| is |" 
1318                                         <<  attributeDescription.size()  <<"| and is more than |" <<  MED_TAILLE_DESC << "|")) ;
1319         
1320         attributesDescriptions += attributeDescription;
1321       }
1322       
1323
1324       int      numberOfGroups  = families[i]->getNumberOfGroups();
1325       string   groupsNames(numberOfGroups*MED_TAILLE_LNOM,'\0') ;
1326       // Recompose the groups names arg for MED
1327       for (int j=0; j < numberOfGroups; j++) {
1328
1329         string groupName = families[i]->getGroupName(j+1);
1330        
1331         if ( groupName.size() > MED_TAILLE_LNOM )
1332           throw MEDEXCEPTION( LOCALIZED(STRING(LOC) << "The size of the group name  n° |" << j+1 << "| of the family |" << families[i]->getName()
1333                                         << "| with identifier |" << families[i]->getIdentifier()  << "| is |" 
1334                                         <<  groupName.size()  <<"| and is more than |" << MED_TAILLE_LNOM << "|")) ;
1335         
1336
1337         int length = min(MED_TAILLE_LNOM,(int)groupName.size());
1338         groupsNames.replace(j*MED_TAILLE_LNOM,length, groupName,0,length);
1339       
1340       }
1341
1342       // test if the family already exists (HDF trick waiting a MED evolution to be replaced)
1343       string dataGroupFam = "/ENS_MAA/"+_meshName+"/FAS/"+families[i]->getName()+"/";  
1344       SCRUTE("|"<<dataGroupFam<<"|");
1345       if ( err =_MEDdatagroupOuvrir(_medIdt,const_cast <char *> (dataGroupFam.c_str()) ) < MED_VALID ) {
1346         SCRUTE(err);
1347
1348         MESSAGE(LOC<<"families[i]->getName().c_str() : "<<families[i]->getName().c_str());
1349         MESSAGE(LOC<<"_meshName.c_str() : "<<_meshName.c_str());
1350         MESSAGE(LOC<<"families[i]->getIdentifier() : "<<families[i]->getIdentifier());
1351         MESSAGE(LOC<<"families[i]->getAttributesIdentifiers() : "<<families[i]->getAttributesIdentifiers()[0]);
1352         MESSAGE(LOC<<"families[i]->getAttributesValues() : "<<families[i]->getAttributesValues()[0]);
1353         MESSAGE(LOC<<"attributesDescriptions.c_str() : "<<attributesDescriptions.c_str());
1354         MESSAGE(LOC<<"numberOfAttributes : "<<numberOfAttributes);
1355         MESSAGE(LOC<<"groupsNames.c_str() : "<<groupsNames.c_str());
1356         MESSAGE(LOC<<"numberOfGroups : "<<numberOfGroups);
1357
1358         err = MEDfamCr( _medIdt, 
1359                         const_cast <char *> ( _meshName.c_str() ),
1360                         const_cast <char *> ( families[i]->getName().c_str() ),
1361                         families[i]->getIdentifier(), 
1362                         families[i]->getAttributesIdentifiers(),
1363                         families[i]->getAttributesValues(),
1364                         const_cast <char *> (attributesDescriptions.c_str()), 
1365                         numberOfAttributes,  
1366                         const_cast <char *> (groupsNames.c_str()), 
1367                         numberOfGroups);
1368         SCRUTE(err);
1369         if ( err != MED_VALID) 
1370           throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't create family |" << families[i]->getName()
1371                                        << "| with identifier |" << families[i]->getIdentifier()  << "| groups names |" 
1372                                        << groupsNames  <<"| and  attributes descriptions |" << attributesDescriptions << "|")) ;
1373       }
1374       else
1375         _MEDdatagroupFermer(_medIdt);
1376
1377
1378     }
1379
1380     END_OF(LOC);
1381     
1382     return MED_VALID;
1383   }
1384   return MED_ERROR;
1385 }
1386
1387
1388 // A FAIRE POUR LES NOEUDS ET LES ELEMENTS ret = MEDfamEcr(