]> SALOME platform Git repositories - modules/med.git/blob - src/MEDMEM/MEDMEM_MedMeshDriver.cxx
Salome HOME
merging in the main branch with the branch br_MedFileV2_2.
[modules/med.git] / src / MEDMEM / MEDMEM_MedMeshDriver.cxx
1 using namespace std;
2 #include "MEDMEM_MedMeshDriver.hxx"
3
4 #include "MEDMEM_DriversDef.hxx"
5
6 #include "MEDMEM_Family.hxx"
7 #include "MEDMEM_Group.hxx"
8 #include "MEDMEM_Coordinate.hxx"
9 #include "MEDMEM_Connectivity.hxx"
10 #include "MEDMEM_Mesh.hxx"
11 #include "MEDMEM_CellModel.hxx"
12 #include "MEDMEM_Grid.hxx"
13
14 using namespace MEDMEM;
15 extern "C" {
16   extern med_idt _MEDdatagroupOuvrir(med_idt pid, char *nom);
17   extern med_err _MEDdatagroupFermer(med_idt id);
18 }
19
20 // Every memory allocation made in the MedDriver members function are desallocated in the Mesh destructor 
21
22 MED_MESH_DRIVER::MED_MESH_DRIVER():
23   GENDRIVER(),
24   _ptrMesh(( MESH *)MED_NULL),
25   _medIdt(MED_INVALID),
26   _meshName(""),
27   _meshNum(MED_INVALID)
28 {
29 }
30
31 MED_MESH_DRIVER::MED_MESH_DRIVER(const string & fileName,
32                                  MESH * ptrMesh,
33                                  MED_EN::med_mode_acces accessMode): 
34   GENDRIVER(fileName,accessMode),
35   _ptrMesh(ptrMesh),
36   _medIdt(MED_INVALID), 
37   _meshName(""),
38   _meshNum(MED_INVALID) 
39 {
40 }
41   
42 MED_MESH_DRIVER::MED_MESH_DRIVER(const MED_MESH_DRIVER & driver): 
43   GENDRIVER(driver),
44   _ptrMesh(driver._ptrMesh),
45   _medIdt(MED_INVALID), 
46   _meshName(driver._meshName),
47   _meshNum(driver._meshNum) 
48 {
49 }
50
51 MED_MESH_DRIVER::~MED_MESH_DRIVER()
52 {
53 }
54
55 void MED_MESH_DRIVER::open()
56   throw (MEDEXCEPTION)
57 {
58   const char * LOC = "MED_MESH_DRIVER::open()" ;
59   BEGIN_OF(LOC);
60   MESSAGE(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode);
61   _medIdt = MED_FR::MEDouvrir( (const_cast <char *> (_fileName.c_str())),(MED_FR::med_mode_acces) _accessMode);
62   MESSAGE(LOC<<" _medIdt : "<< _medIdt );
63   if (_medIdt > 0) 
64     _status = MED_OPENED; 
65   else {
66     _medIdt = MED_INVALID;
67     _status = MED_CLOSED;
68     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Could not open file "<<_fileName<<" in mode "<<_accessMode));
69   }
70   
71   END_OF(LOC);
72 }
73   
74 void MED_MESH_DRIVER::close()
75   throw (MEDEXCEPTION)
76 {
77   const char * LOC = "MED_MESH_DRIVER::close() " ;
78   BEGIN_OF(LOC);
79   int err = 0;
80   if ( _status == MED_OPENED) {
81     err=MED_FR::MEDfermer(_medIdt);
82     H5close(); // If we call H5close() all the files are closed.
83     if (err != 0)
84       throw MEDEXCEPTION( LOCALIZED(STRING(LOC)
85                                     <<" Error when closing file !"
86                                     )
87                           );
88     MESSAGE(LOC <<": _medIdt= " << _medIdt );
89     MESSAGE(LOC<<": MEDfermer : err    = " << err );
90     _status = MED_CLOSED;
91     _medIdt = MED_INVALID;
92   }
93   END_OF(LOC);
94 }
95
96 void    MED_MESH_DRIVER::setMeshName(const string & meshName) { _meshName = meshName; };
97 string  MED_MESH_DRIVER::getMeshName() const { return _meshName; };
98
99 //A FAIRE UTILISER LES MAPS...
100 const MED_FR::med_geometrie_element  MED_MESH_DRIVER::all_cell_type[MED_NBR_GEOMETRIE_MAILLE]=
101   { 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,
102     MED_FR::MED_TETRA4,MED_FR::MED_PYRA5,MED_FR::MED_PENTA6,MED_FR::MED_HEXA8,MED_FR::MED_TETRA10,MED_FR::MED_PYRA13,
103     MED_FR::MED_PENTA15, MED_FR::MED_HEXA20};
104
105 const char * const MED_MESH_DRIVER::all_cell_type_tab [MED_NBR_GEOMETRIE_MAILLE]=
106   { "MED_POINT1","MED_SEG2","MED_SEG3","MED_TRIA3","MED_QUAD4","MED_TRIA6","MED_QUAD8",
107     "MED_TETRA4","MED_PYRA5","MED_PENTA6","MED_HEXA8","MED_TETRA10","MED_PYRA13",
108     "MED_PENTA15","MED_HEXA20"};
109
110
111 //---------------------------------- RDONLY PART -------------------------------------------------------------
112
113 MED_MESH_RDONLY_DRIVER::MED_MESH_RDONLY_DRIVER(): MED_MESH_DRIVER()
114 {
115 }
116   
117 MED_MESH_RDONLY_DRIVER::MED_MESH_RDONLY_DRIVER(const string & fileName,
118                                                MESH * ptrMesh):
119   MED_MESH_DRIVER(fileName,ptrMesh,MED_RDONLY)
120
121   MESSAGE("MED_MESH_RDONLY_DRIVER::MED_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
122 }
123   
124 MED_MESH_RDONLY_DRIVER::MED_MESH_RDONLY_DRIVER(const MED_MESH_RDONLY_DRIVER & driver): 
125   MED_MESH_DRIVER(driver)
126 {
127 }
128
129 MED_MESH_RDONLY_DRIVER::~MED_MESH_RDONLY_DRIVER()
130 {
131   //MESSAGE("MED_MESH_RDONLY_DRIVER::~MED_MESH_RDONLY_DRIVER() has been destroyed");
132 }
133   
134 GENDRIVER * MED_MESH_RDONLY_DRIVER::copy(void) const
135 {
136   return new MED_MESH_RDONLY_DRIVER(*this);
137 }
138
139 void MED_MESH_RDONLY_DRIVER::read(void)
140   throw (MEDEXCEPTION)
141 {
142   const char * LOC = "MED_MESH_RDONLY_DRIVER::read() : " ;
143   BEGIN_OF(LOC);
144   if (_status!=MED_OPENED)
145     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The _idt of file " << _fileName << " is : " << _medIdt <<  " (the file is not opened)." )) ;
146
147   _ptrMesh->_name =  _meshName;
148
149   SCRUTE(_ptrMesh->getIsAGrid());
150
151   if (_ptrMesh->getIsAGrid())
152     {
153       getGRID( );
154
155       // always call getFAMILY : families are requiered !!!!
156
157 //        int nbFam = MEDnFam(_medIdt,
158 //                        const_cast <char *> (_meshName.c_str()),
159 //                        0,
160 //                        MED_FR::MED_FAMILLE);
161 //        if (nbFam > 0)
162         {
163 //        getFAMILY();
164     
165           if (getFAMILY()!=MED_VALID)
166             throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getFAMILY when the mesh is a grid")) ;
167
168           buildAllGroups(_ptrMesh->_groupNode,_ptrMesh->_familyNode) ;
169         }
170
171       END_OF(LOC);
172       return;
173     }
174
175   if (getCOORDINATE()!=MED_VALID)
176     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getCOORDINATE"  )) ;
177  
178   if (getCONNECTIVITY()!=MED_VALID)
179     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getCOONECTIVITY")) ;
180   
181   if (getFAMILY()!=MED_VALID)
182     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getFAMILY"      )) ;
183   
184   updateFamily();
185
186   // we build all groups
187   // on node
188   buildAllGroups(_ptrMesh->_groupNode,_ptrMesh->_familyNode) ;
189   // on cell
190   buildAllGroups(_ptrMesh->_groupCell,_ptrMesh->_familyCell) ;
191   // on face
192   buildAllGroups(_ptrMesh->_groupFace,_ptrMesh->_familyFace) ;
193   // on edge
194   buildAllGroups(_ptrMesh->_groupEdge,_ptrMesh->_familyEdge) ;
195
196 //   MESSAGE(LOC<<"Checking of CellModel !!!!!!!");
197
198 //   int nbOfTypes =  _ptrMesh->_connectivity->_numberOfTypes;
199 //    for(int i=0;i<nbOfTypes;i++)
200 //      {
201 //        MESSAGE(LOC << _ptrMesh->_connectivity->_type[i]) ;
202 //      }
203
204   END_OF(LOC);
205 }
206
207 //=======================================================================
208 //function : getGRID
209 //purpose  : 
210 //=======================================================================
211
212 void MED_MESH_RDONLY_DRIVER::getGRID()
213 {
214   const char * LOC = "MED_MESH_RDONLY_DRIVER::getGRID() : " ;
215   BEGIN_OF(LOC);
216   
217   if (_status!=MED_OPENED)
218     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "med file is not opened"));
219   
220   GRID * ptrGrid = (GRID *) _ptrMesh;
221     
222   SCRUTE(ptrGrid);
223
224   int err, i;
225
226   // Read the dimension of the mesh <_meshName>
227   int MeshDimension = MED_FR::MEDdimLire(_medIdt, const_cast <char *>
228                                          (_meshName.c_str())) ;
229
230   if (MeshDimension == MED_INVALID)
231     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The mesh dimension |" <<
232                                  MeshDimension << "| seems to be incorrect " <<
233                                  "for the mesh : |" << _meshName << "|")) ;
234
235   _ptrMesh->_meshDimension = MeshDimension;
236
237   // Read or get the dimension of the space for the mesh <_meshName>
238   int SpaceDimension = MeshDimension;
239
240   int SpaceDimensionRead = MED_FR::MEDdimEspaceLire(_medIdt,
241                                                     const_cast <char *>
242                                                     (_meshName.c_str())) ;
243
244   if (SpaceDimensionRead != MED_INVALID) SpaceDimension = SpaceDimensionRead;
245
246   _ptrMesh->_spaceDimension = SpaceDimension;
247
248   MED_FR::med_repere rep ;
249   string tmp_nom_coord (MED_TAILLE_PNOM*(_ptrMesh->_spaceDimension)+1,' ');
250   string tmp_unit_coord(MED_TAILLE_PNOM*(_ptrMesh->_spaceDimension)+1,' ');
251   char * tmp_nom = (const_cast <char *> ( tmp_nom_coord.c_str())  ) ;
252   char * tmp_unit= (const_cast <char *> ( tmp_unit_coord.c_str()) ) ;
253
254   // Read Array length
255   int * ArrayLen[] = { & ptrGrid->_iArrayLength,
256                        & ptrGrid->_jArrayLength,
257                        & ptrGrid->_kArrayLength  };
258
259   med_type_grille gridType = ptrGrid->getGridType();
260
261   int NumberOfNodes;
262
263   if (gridType == MED_EN::MED_GRILLE_STANDARD)
264     {
265       NumberOfNodes = MED_FR::MEDnEntMaa(_medIdt,
266                                          const_cast <char *>
267                                          (_ptrMesh->_name.c_str()),
268                                          MED_FR::MED_COOR,MED_FR::MED_NOEUD,
269                                          MED_FR::MED_NONE,MED_FR::MED_NOD);
270
271       if ( NumberOfNodes <= MED_VALID )
272         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"The number of nodes |" <<
273                                      NumberOfNodes <<
274                                      "| seems to be incorrect "
275                                      << "for the mesh : |" <<
276                                      _meshName << "|" )) ;
277
278       _ptrMesh->_numberOfNodes = NumberOfNodes ;
279
280       // create coordinates and its structure
281       _ptrMesh->_coordinate = new COORDINATE(SpaceDimension,NumberOfNodes,
282                                              MED_EN::MED_FULL_INTERLACE);
283
284       int * structure = new int[MeshDimension];
285
286       err = MED_FR::MEDstructureCoordLire(_medIdt,
287                                           const_cast <char *>
288                                           (_ptrMesh->_name.c_str()),
289                                           MeshDimension,structure);
290
291       if (err != MED_VALID)
292         throw MEDEXCEPTION(STRING(LOC) <<"Error in reading the structure of grid : |" << _meshName << "|" ) ;
293       
294       for (int idim = 0; idim < MeshDimension; idim++)
295         ArrayLen [idim][0] = structure[idim];
296       
297       delete [] structure;
298
299       err = MEDcoordLire(_medIdt,
300                          const_cast <char *> (_ptrMesh->_name.c_str()),
301                          _ptrMesh->_spaceDimension,
302                          //const_cast <double *> ( _ptrMesh->_coordinate->_coordinate->get(MED_EN::MED_FULL_INTERLACE) ),
303                          const_cast <double *> ( _ptrMesh->_coordinate->_coordinate.get(MED_EN::MED_FULL_INTERLACE) ),
304                          MED_FR::MED_FULL_INTERLACE,
305                          MED_ALL, // we read all the coordinates
306                          NULL,    // we don't use a profile
307                          0,       // so the profile's size is 0
308                          &rep,tmp_nom,tmp_unit);
309
310       if (err != MED_VALID)
311         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't read coordinates of the |" <<
312                                      NumberOfNodes << "| nodes for the mesh : |" <<
313                                      _meshName << "| of space dimension |" <<
314                                      SpaceDimension << "| with units names |" <<
315                                      tmp_nom << "| and units |" <<
316                                      tmp_unit << " |")) ;
317
318       ptrGrid->_is_coordinates_filled = true;
319     }
320   else if ((gridType == MED_EN::MED_GRILLE_CARTESIENNE) ||
321            (gridType == MED_EN::MED_GRILLE_POLAIRE))
322     {
323       NumberOfNodes = 1;
324
325       double * Array[] = { (double*) 0, (double*) 0, (double*) 0 };
326
327       for (int idim = 0; idim < _ptrMesh->_meshDimension; ++idim)
328         {
329           MED_FR::med_table table;
330           if (idim == 0) table = MED_FR::MED_COOR_IND1;
331           else if (idim == 1) table = MED_FR::MED_COOR_IND2;
332           else if (idim == 2) table = MED_FR::MED_COOR_IND3;
333
334           int length = MED_FR::MEDnEntMaa(_medIdt,
335                                           const_cast <char *> (_ptrMesh->_name.c_str()),
336                                           table,MED_FR::MED_NOEUD,
337                                           MED_FR::MED_NONE,
338                                           MED_FR::MED_NOD);
339           if ( length <= MED_VALID )
340             throw MEDEXCEPTION(STRING(LOC) <<"The number of nodes |" << length <<
341                                "| seems to be incorrect "
342                                << "for the mesh : |" << _meshName << "|" ) ;
343           
344           ArrayLen [idim][0] = length;
345           NumberOfNodes *= length;
346
347           Array [idim] = new double [ length ];
348
349           err = MED_FR::MEDindicesCoordLire(_medIdt, const_cast <char *>
350                                             (_ptrMesh->_name.c_str()),
351                                             _ptrMesh->_meshDimension,
352                                             Array [idim], length, (idim+1),
353                                             tmp_nom+(idim*MED_TAILLE_PNOM),
354                                             tmp_unit+(idim*MED_TAILLE_PNOM));
355
356           if (err != MED_VALID)
357             throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Error in reading coordinates indices " <<
358                                          idim << "of the grid : |" <<
359                                          _meshName << "|" )) ;
360         }
361
362       ptrGrid->_iArray = Array[0];
363       ptrGrid->_jArray = Array[1];
364       ptrGrid->_kArray = Array[2];
365
366       _ptrMesh->_numberOfNodes = NumberOfNodes ;
367     
368       // create coordinates
369       _ptrMesh->_coordinate = new COORDINATE(SpaceDimension,NumberOfNodes,
370                                              MED_EN::MED_FULL_INTERLACE);
371
372       if (gridType == MED_EN::MED_GRILLE_CARTESIENNE)
373         rep = MED_FR::MED_CART;
374       else if (gridType == MED_EN::MED_GRILLE_POLAIRE)
375         {
376           if (SpaceDimension == 2) rep = MED_FR::MED_CYL;
377           else if (SpaceDimension == 3) rep = MED_FR::MED_SPHER;
378         }
379     }
380   else
381     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<" bad grid type : " << gridType));
382
383   // set coordinate names
384
385   for (i=0; i<_ptrMesh->_spaceDimension; ++i ) {
386     string myStringName(tmp_nom,i*MED_TAILLE_PNOM,MED_TAILLE_PNOM) ;
387     string myStringUnit(tmp_unit,i*MED_TAILLE_PNOM,MED_TAILLE_PNOM) ;
388     // suppress space at the end
389     int j ;
390     for(j=MED_TAILLE_PNOM-1;j>=0;j--)
391       if (myStringName[j] != ' ') break ;
392     _ptrMesh->_coordinate->_coordinateName[i]=string(myStringName,0,j+1);
393     for(j=MED_TAILLE_PNOM-1;j>=0;j--)
394       if (myStringUnit[j] != ' ') break ;
395     _ptrMesh->_coordinate->_coordinateUnit[i]=string(myStringUnit,0,j+1);
396   }
397
398   string coordinateSystem = "UNDEFINED";
399
400   if( rep == MED_FR::MED_CART) coordinateSystem = "CARTESIAN";
401   else if ( rep == MED_FR::MED_CYL) coordinateSystem = "CYLINDRICAL";
402   else if ( rep == MED_FR::MED_SPHER) coordinateSystem = "SPHERICAL";
403
404   _ptrMesh->_coordinate->setCoordinatesSystem(coordinateSystem);
405
406   END_OF(LOC);
407 }
408
409 //=======================================================================
410 //function : getCOORDINATE
411 // A FAIRE : RENVOYER DU VOID
412 //=======================================================================
413 int  MED_MESH_RDONLY_DRIVER::getCOORDINATE()
414 {
415   const char * LOC = "MED_MESH_RDONLY_DRIVER::getCOORDINATE() : " ;
416
417   BEGIN_OF(LOC);
418
419   if (_status==MED_OPENED)
420     {
421       int err ;
422       
423       // Read the dimension of the mesh <_meshName>
424       int MeshDimension = MED_FR::MEDdimLire(_medIdt, const_cast <char *>
425                                              (_meshName.c_str())) ;
426
427       if ( MeshDimension == MED_INVALID ) 
428         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The mesh dimension |" <<
429                                      MeshDimension <<
430                                      "| seems to be incorrect " <<
431                                      "for the mesh : |" << _meshName << "|")) ;
432
433       _ptrMesh->_meshDimension = MeshDimension;
434
435       // Read or get the dimension of the space for the mesh <_meshName>
436       int SpaceDimension = MeshDimension;
437
438       int SpaceDimensionRead = MED_FR::MEDdimEspaceLire(_medIdt,
439                                                         const_cast <char *>
440                                                         (_meshName.c_str())) ;
441
442       if (SpaceDimensionRead  != MED_INVALID)
443         SpaceDimension = SpaceDimensionRead;
444
445       _ptrMesh->_spaceDimension = SpaceDimension;
446
447       // Read the number of nodes used in the mesh <_meshName>
448       // to be able to create a COORDINATE object
449       int NumberOfNodes=MEDnEntMaa(_medIdt,
450                                    const_cast <char *> (_meshName.c_str()),
451                                    MED_FR::MED_COOR,
452                                    MED_FR::MED_NOEUD,
453                                    (MED_FR::med_geometrie_element) MED_NONE,
454                                    (MED_FR::med_connectivite)      MED_NONE);
455       if ( NumberOfNodes <= MED_VALID )
456         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"The number of nodes |" << NumberOfNodes << "| seems to be incorrect "
457                                      << "for the mesh : |" << _meshName << "|" )) ;
458       _ptrMesh->_numberOfNodes = NumberOfNodes ;
459
460       // create a COORDINATE object
461       _ptrMesh->_coordinate = new COORDINATE(SpaceDimension, NumberOfNodes, MED_EN::MED_FULL_INTERLACE);
462       
463       MED_FR::med_repere rep ; // ATTENTION ---> DOIT ETRE INTEGRE DS MESH EF: FAIT NON?
464       string tmp_nom_coord (MED_TAILLE_PNOM*(_ptrMesh->_spaceDimension)+1,'\0');
465       string tmp_unit_coord(MED_TAILLE_PNOM*(_ptrMesh->_spaceDimension)+1,'\0');
466       char * tmp_nom = (const_cast <char *> ( tmp_nom_coord.c_str())  ) ;
467       char * tmp_unit= (const_cast <char *> ( tmp_unit_coord.c_str()) ) ;
468
469       err=MEDcoordLire(_medIdt,
470                        const_cast <char *> (_ptrMesh->_name.c_str()),
471                        _ptrMesh->_spaceDimension,
472                        //const_cast <double *> ( _ptrMesh->_coordinate->_coordinate->get(MED_EN::MED_FULL_INTERLACE) ),
473                        const_cast <double *> ( _ptrMesh->_coordinate->_coordinate.get(MED_EN::MED_FULL_INTERLACE) ),
474                        MED_FR::MED_FULL_INTERLACE,
475                        MED_ALL,                      // we read all the coordinates
476                        NULL,                         // we don't use a profile
477                        0,                            // so the profile's size is 0
478                        &rep,tmp_nom,tmp_unit);
479       if (err != MED_VALID)
480         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't read coordinates of the |" << NumberOfNodes << "| nodes "
481                                      << "for the mesh : |" << _meshName 
482                                      << "| of space dimension |" << SpaceDimension 
483                                      << "| with units names |"   << tmp_nom
484                                      << "| and units |"          << tmp_unit
485                                      << " |")) ;
486       
487
488       for (int i=0;i<_ptrMesh->_spaceDimension;i++) {
489         string myStringName(tmp_nom,i*MED_TAILLE_PNOM,MED_TAILLE_PNOM) ;
490         string myStringUnit(tmp_unit,i*MED_TAILLE_PNOM,MED_TAILLE_PNOM) ;
491         // suppress space at the end
492         int j ;
493         for(j=MED_TAILLE_PNOM-1;j>=0;j--)
494           if (myStringName[j] != ' ') break ;
495         _ptrMesh->_coordinate->_coordinateName[i]=string(myStringName,0,j+1);
496         for(j=MED_TAILLE_PNOM-1;j>=0;j--)
497           if (myStringUnit[j] != ' ') break ;
498         _ptrMesh->_coordinate->_coordinateUnit[i]=string(myStringUnit,0,j+1);
499       }
500
501       // Pourquoi le stocker sous forme de chaîne ?
502       switch (rep)
503         {
504         case MED_FR::MED_CART : 
505           {
506             _ptrMesh->_coordinate->_coordinateSystem = "CARTESIAN";
507             break ;
508           }
509         case MED_FR::MED_CYL :
510           {
511             _ptrMesh->_coordinate->_coordinateSystem = "CYLINDRICAL";
512             break ;
513           }
514         case MED_FR::MED_SPHER :
515           {
516             _ptrMesh->_coordinate->_coordinateSystem = "SPHERICAL";
517             break ;
518           }
519         default :
520           {
521             _ptrMesh->_coordinate->_coordinateSystem = "UNDEFINED"; // ?Erreur ?
522             break ;
523           }
524         }
525
526       // Read the unused optional node Names
527       char * tmp_node_name = new char[NumberOfNodes*MED_TAILLE_PNOM+1];
528       tmp_node_name[NumberOfNodes]='\0' ;
529       err=MEDnomLire(_medIdt,const_cast <char*> (_ptrMesh->_name.c_str()),
530                      tmp_node_name,NumberOfNodes*MED_TAILLE_PNOM,MED_FR::MED_NOEUD,
531                      (MED_FR::med_geometrie_element) MED_NONE);
532       if (err == MED_VALID) 
533         MESSAGE(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : WARNING : Nodes have names but we do not read them !");
534       delete[] tmp_node_name ;
535
536
537       // ??? Read the unused optional node Numbers ???
538       int * tmp_node_number = new int[NumberOfNodes] ;
539       err=MEDnumLire(_medIdt,const_cast <char*> (_ptrMesh->_name.c_str()),
540                      tmp_node_number,NumberOfNodes,MED_FR::MED_NOEUD,(MED_FR::med_geometrie_element)0);
541       if (err == MED_VALID) {
542         // INFOS(LOC<<"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING");
543         // INFOS(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : WARNING : Nodes have numbers but we do not take care of them !");
544         // INFOS(LOC<<"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING");
545         MESSAGE(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : Nodes have numbers, we DO TAKE care of them !");
546         _ptrMesh->_coordinate->_nodeNumber.set(NumberOfNodes) ; 
547         memcpy((int*)_ptrMesh->_coordinate->_nodeNumber,tmp_node_number,sizeof(int)*NumberOfNodes) ;
548         
549         //////////////////////////////////////////////////////////////////////////////////////
550         ///  Modification pour prise en compte de la numérotation optionnelle des noeuds   ///
551         //////////////////////////////////////////////////////////////////////////////////////
552         ///
553         /// Calcule _optionnalToCanonicNodesNumbers de telle sorte que _optionnalToCanonicNodesNumbers[OptionnalNumber]==CanonicNumber
554         
555 //      _ptrMesh->_arePresentOptionnalNodesNumbers=1;
556 //      for (int canonicNumber=1;canonicNumber<=NumberOfNodes;canonicNumber++) _ptrMesh->_optionnalToCanonicNodesNumbers[tmp_node_number[canonicNumber-1]]=canonicNumber;
557 // ICI RETOUR A LA NORMALE::: AUCUNE PRISE EN COMPTE D'UN NUMEROTATION OPTIONNEL
558         _ptrMesh->_arePresentOptionnalNodesNumbers=0;
559       } 
560       else _ptrMesh->_arePresentOptionnalNodesNumbers=0;
561
562         //////////////////////////////////////////////////////////////////////////////////////
563
564       delete[] tmp_node_number ;
565       
566       END_OF(LOC);
567       return MED_VALID;
568     }
569   return MED_ERROR;
570 }
571
572
573 int MED_MESH_RDONLY_DRIVER::getCONNECTIVITY() 
574 {
575   const char * LOC = "MED_MESH_RDONLY_DRIVER::getCONNECTIVITY : " ;
576   BEGIN_OF(LOC);
577
578   if (_status==MED_OPENED)
579     {
580
581       int err = 0 ;
582       // read MED_CELL connectivity
583       CONNECTIVITY * Connectivity     = new CONNECTIVITY(MED_CELL) ;
584       Connectivity->_numberOfNodes    = _ptrMesh->_numberOfNodes ;   // EF : Pourquoi cet attribut est-il dans MESH et non dans COORDINATE ?
585
586       // Try to read nodal connectivity of the cells <Connectivity->_nodal>
587       // then try to read descending connectivity    <Connectivity->_descending>
588       // if neither nodal nor descending connectivity exists
589       // throw an exception.
590       err = getNodalConnectivity(Connectivity) ;
591       if (err!=MED_VALID) {
592         Connectivity->_typeConnectivity = MED_DESCENDING ;
593         err = getDescendingConnectivity(Connectivity) ;
594       } else 
595         getDescendingConnectivity(Connectivity) ; // we read it if there is one
596       
597       if (err!=MED_VALID) {
598         delete Connectivity ;
599         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "We could not read any Connectivity")) ;
600       }
601
602       //      _ptrMesh->_meshDimension = Connectivity->_entityDimension ; 
603
604       // At this point Connectivity->_typeConnectivity is either NODAL or DESCENDING
605       // If both connectivities are found Connectivity->_typeConnectivity is NODAL
606       // If space dimension is 3 
607       // try to read the nodal connectivity of the faces <ConnectivityFace->_nodal> then
608       // try to read the descending connectivity <ConnectivityFace->_descending>
609       // if there is no descending connectivity and the CELLS are
610       // defined in descending mode then throw an exception
611
612       // PROVISOIRE : if we have some face or edge in MED_MAILLE, we don't read more. There could not be have face or edge !!!!
613
614       if(Connectivity->_constituent==NULL) {
615
616       SCRUTE(_ptrMesh->_meshDimension);
617       SCRUTE(Connectivity->_entityDimension);
618       if (_ptrMesh->_meshDimension == 3) {
619         MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DES FACES..." );
620         CONNECTIVITY * ConnectivityFace = new CONNECTIVITY(MED_EN::MED_FACE) ;
621         ConnectivityFace->_typeConnectivity = Connectivity->_typeConnectivity ; // NODAL or DESCENDING
622         SCRUTE(ConnectivityFace->_typeConnectivity);
623         if (Connectivity->_typeConnectivity == MED_DESCENDING) {
624           MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DESCENDANTE DES FACES" );
625           err = getDescendingConnectivity(ConnectivityFace) ;
626           if (err!=MED_VALID)
627             throw MEDEXCEPTION ( LOCALIZED(STRING(LOC) << "No FACE in descending connectivity")) ;
628           getNodalConnectivity(ConnectivityFace) ; // if any !
629         } else {
630           MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE NODALE DES FACES" );
631           err = getNodalConnectivity(ConnectivityFace) ;
632           if (err!=MED_VALID) { // or error ????? we are in NODAL mode.
633             err = getDescendingConnectivity(ConnectivityFace) ;
634           } else
635             getDescendingConnectivity(ConnectivityFace); // if any !
636         }
637         if (err!=MED_VALID) {
638           delete ConnectivityFace ;
639           MESSAGE(LOC<<"No FACE defined.") ;
640         } else {
641           MESSAGE(LOC<<" SAUVEGARDE DE LA CONNECTIVITE DES FACES DANS L'OBJET CONNECTIVITY" );
642           Connectivity->_constituent=ConnectivityFace ; 
643         }
644       }
645       
646       // read MED_EDGE connectivity
647       if (_ptrMesh->_meshDimension > 1) { // we are in 3 or 2D 
648         MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DES ARRETES...." );
649         CONNECTIVITY * ConnectivityEdge = new CONNECTIVITY(MED_EDGE) ;
650         ConnectivityEdge->_typeConnectivity = Connectivity->_typeConnectivity ;
651         if (Connectivity->_typeConnectivity == MED_DESCENDING) {
652           MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DESCENDANTE DES ARRETES" );
653           err = getDescendingConnectivity(ConnectivityEdge) ;
654           if (err!=MED_VALID)
655             throw MEDEXCEPTION ( LOCALIZED(STRING(LOC) << "No EDGE in descending connectivity")) ;
656           getNodalConnectivity(ConnectivityEdge) ; // if any !
657         } else {
658           MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE NODALE DES ARRETES" );
659           err = getNodalConnectivity(ConnectivityEdge) ;
660           if (err!=MED_VALID) { // or error ????? we are in NODAL mode.
661             err = getDescendingConnectivity(ConnectivityEdge) ;
662           } else
663             getDescendingConnectivity(ConnectivityEdge) ; // if any !
664         }
665         if (err!=MED_VALID) {
666           delete ConnectivityEdge ;
667           MESSAGE(LOC<<"No EDGE defined.") ;
668         } else {
669           if (_ptrMesh->_meshDimension == 3)
670             if (Connectivity->_constituent != NULL)
671               Connectivity->_constituent->_constituent=ConnectivityEdge ;
672             else
673               throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<< "EDGE defined but there are no FACE !")) ;
674           else { // IN 2D
675             MESSAGE(LOC<<" SAUVEGARDE DE LA CONNECTIVITE DES ARETES DANS L'OBJET CONNECTIVITY" );
676             Connectivity->_constituent=ConnectivityEdge ;
677           }
678         }
679       }
680       }
681       _ptrMesh->_connectivity  = Connectivity ;                                      
682
683       // all right !
684
685       // we have read all connectivity in file, now we must build descending connectivity if necessary !
686
687       // If connectivity descending is defined, we have nothing to do, all constituent are defined !
688       // If connectivity is only nodal, we must rebuild descending if we have some contituent !
689
690       //A FAIRE !!!!
691 //        if (Connectivity->_descending == NULL)
692 //      if (Connectivity->_constituent != NULL){
693 //        // update Connectivity->_constituent
694 //        CONNECTIVITY * myConstituentOld = Connectivity->_constituent ;
695 //        Connectivity->_constituent = (CONNECTIVITY *)NULL ;
696 //        Connectivity->calculateDescendingConnectivity() ;
697           
698 //      }
699       
700       END_OF(LOC);
701       return MED_VALID;
702     }
703   return MED_ERROR;
704 }
705
706 int MED_MESH_RDONLY_DRIVER::getNodalConnectivity(CONNECTIVITY * Connectivity) 
707 {
708   const char * LOC = "MED_MESH_RDONLY_DRIVER::getNodalConnectivity : " ;
709   BEGIN_OF(LOC);
710   if (_status==MED_OPENED)
711     {
712       // Get the type of entity to work on (previously set in the Connectivity Object)
713       MED_FR::med_entite_maillage Entity = (MED_FR::med_entite_maillage) Connectivity->getEntity();
714
715       // Get the number of cells of each type & store it in <tmp_cells_count>.
716       int * tmp_cells_count = new int[MED_NBR_GEOMETRIE_MAILLE] ;
717       int i;
718       for (i=1;i<MED_NBR_GEOMETRIE_MAILLE;i++) {                       // EF :ON SCANNE DES GEOMETRIES INUTILES, UTILISER LES MAPS
719         tmp_cells_count[i]=MEDnEntMaa(_medIdt,(const_cast <char *> (_ptrMesh->_name.c_str())),
720                                       MED_FR::MED_CONN,(MED_FR::med_entite_maillage) Entity,
721                                       all_cell_type[i],MED_FR::MED_NOD); 
722
723
724         // Get the greatest dimension of the cells : Connectivity->_entityDimension
725         // We suppose there is no cells used as faces in MED 2.2.x , this is forbidden !!!
726         // In version prior to 2.2.x, it is possible
727         if (tmp_cells_count[i]>0) { 
728           Connectivity->_entityDimension=all_cell_type[i]/100;  
729           Connectivity->_numberOfTypes++;
730         }
731       }
732       
733
734       // If there is no nodal connectivity, we quit !
735       if ( Connectivity->_numberOfTypes == 0 ) {
736         delete[] tmp_cells_count ;
737         return MED_ERROR ;
738       }
739
740       // if MED version < 2.2.x, we read only entity with dimention = Connectivity->_entityDimension. Lesser dimension are face or edge !
741
742       char version_med[10] ;
743       if ( MEDfichEntete(_medIdt,MED_FR::MED_VERSION,version_med) != 0 ){
744         // error : we suppose we have not a good med file !
745         delete[] tmp_cells_count ;
746         return MED_ERROR ;
747       }
748
749       // we get MED version number
750       // If MED version is < 2.2 then the cells which dimension
751       // is lesser than the main dimension ( Connectivity->_entityDimension )
752       // are either faces or edges
753
754       //        string medVersion(version_med);
755       //        int firstNumber = 
756       int * tmpEdgeCount = new int[MED_NBR_GEOMETRIE_MAILLE] ;
757       tmpEdgeCount[0]     = 0 ;
758       int numberOfEdgesTypes = 0;
759       int * tmpFaceCount = new int[MED_NBR_GEOMETRIE_MAILLE] ;
760       tmpFaceCount[0]     = 0 ;
761       int numberOfFacesTypes = 0;
762   
763       if ((version_med != "2.2")&(Entity==MED_FR::MED_MAILLE)) {
764         
765         Connectivity->_numberOfTypes=0;
766         
767         for ( i=1;i<MED_NBR_GEOMETRIE_MAILLE;i++) {
768           tmpFaceCount[i]=0;
769           tmpEdgeCount[i]=0;
770           if (tmp_cells_count[i]!=0) {
771             int dimension = all_cell_type[i]/100 ;
772             if (Connectivity->_entityDimension==dimension) 
773               Connectivity->_numberOfTypes++ ;
774             
775             if (dimension == 2)
776               if (Connectivity->_entityDimension==3) {
777                 tmpFaceCount[i]=tmp_cells_count[i] ;
778                 tmp_cells_count[i]=0 ;
779                 numberOfFacesTypes++;
780               }
781             if (dimension == 1)
782               if (Connectivity->_entityDimension>dimension) {
783                 tmpEdgeCount[i]=tmp_cells_count[i] ;
784                 tmp_cells_count[i]=0;
785                 numberOfEdgesTypes++ ;
786               }
787           }
788         }
789       }
790
791       // bloc to read CELL :
792       {
793       // Prepare an array of indexes on the different cell types to create a MEDSKYLINEARRAY
794       // We use <tmp_cells_count> to calculate <Connectivity->_count> then we release it
795         Connectivity->_geometricTypes = new MED_EN::medGeometryElement [Connectivity->_numberOfTypes]   ;  // Double emploi pour des raisons pratiques 
796         Connectivity->_type           = new CELLMODEL                  [Connectivity->_numberOfTypes]   ;  //
797         Connectivity->_count          = new int                        [Connectivity->_numberOfTypes+1] ;
798         Connectivity->_count[0]       = 1;
799         
800         int size = 0 ; 
801         int typeNumber=1 ;
802         int i;
803         for ( i=1;i<MED_NBR_GEOMETRIE_MAILLE;i++)  { // no point1 cell type (?)
804           if (tmp_cells_count[i]>0) {
805             Connectivity->_count[typeNumber]=Connectivity->_count[typeNumber-1]+tmp_cells_count[i];
806
807             CELLMODEL t( (MED_EN::medGeometryElement) MED_MESH_DRIVER::all_cell_type[i]) ;
808             Connectivity->_type[typeNumber-1]=t ;
809             
810             Connectivity->_geometricTypes[typeNumber-1]=( MED_EN::medGeometryElement) MED_MESH_DRIVER::all_cell_type[i] ;
811             
812             // probleme avec les mailles de dimension < a dimension du maillage :
813             // 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 !!!
814
815               
816             size+=tmp_cells_count[i]*((MED_MESH_DRIVER::all_cell_type[i])%100) ;
817             
818             MESSAGE(LOC
819                     << Connectivity->_count[typeNumber]-1 << " cells of type " 
820                     << all_cell_type_tab[i] ); 
821             typeNumber++;
822           }
823         }
824         
825         // Creation of the MEDSKYLINEARRAY
826         //Connectivity->_nodal = new MEDSKYLINEARRAY(Connectivity->_count[Connectivity->_numberOfTypes]-1,size) ; 
827         //int * NodalIndex = Connectivity->_nodal->getIndex() ;
828         int * NodalValue = new int[size] ;
829         int * NodalIndex = new int[Connectivity->_count[Connectivity->_numberOfTypes]] ;
830         NodalIndex[0]=1 ;
831         
832         // Fill the MEDSKYLINEARRAY by reading the MED file.
833         int j=0;
834         for ( i=0;i<Connectivity->_numberOfTypes;i++) {
835           int multi = 0 ;
836           MED_FR::med_geometrie_element med_type = (MED_FR::med_geometrie_element) Connectivity->_type[i].getType() ;
837 //        if ( Connectivity->_type[i].getDimension() < Connectivity->_entityDimension) 
838           if (Connectivity->_entity == MED_CELL)
839             if ( Connectivity->_type[i].getDimension() < _ptrMesh->_spaceDimension) 
840               multi=1;
841           
842           //      int NumberOfCell = Connectivity->_count[i+1]-Connectivity->_count[i] ;
843           int NumberOfNodeByCell = Connectivity->_type[i].getNumberOfNodes() ;
844           
845           // initialise index
846           for ( j=Connectivity->_count[i]; j<Connectivity->_count[i+1];j++)
847             NodalIndex[j]=NodalIndex[j-1]+NumberOfNodeByCell ; 
848
849           int tmp_numberOfCells = Connectivity->_count[i+1]-Connectivity->_count[i] ;
850           int * tmp_ConnectivityArray = new int[(NumberOfNodeByCell+multi)*tmp_numberOfCells];
851           
852 //        int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()),
853 //                            Connectivity->_entityDimension,tmp_ConnectivityArray,
854 //                            MED_FR::MED_FULL_INTERLACE,NULL,0,Entity,med_type,MED_FR::MED_NOD);
855           int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()),
856                               _ptrMesh->_spaceDimension,tmp_ConnectivityArray,
857                               MED_FR::MED_FULL_INTERLACE,NULL,0,Entity,med_type,MED_FR::MED_NOD);
858
859           if ( err != MED_VALID) {
860             delete[] tmp_ConnectivityArray;
861             delete[] tmp_cells_count;
862             delete[] tmpFaceCount;
863             delete[] tmpEdgeCount;
864             MESSAGE(LOC<<": MEDconnLire returns "<<err) ;
865             return MED_ERROR ;
866           }
867
868           int * ConnectivityArray = NodalValue + NodalIndex[Connectivity->_count[i]-1]-1 ;
869
870          // version originale sans prise en compte des numéros optionnels
871          //
872           for ( j=0; j<tmp_numberOfCells; j++) for (int k=0; k<NumberOfNodeByCell; k++) 
873             ConnectivityArray[j*NumberOfNodeByCell+k]=tmp_ConnectivityArray[j*(NumberOfNodeByCell+multi)+k] ;
874
875         //////////////////////////////////////////////////////////////////////////////////////
876         ///  Modification pour prise en compte de la numérotation optionnelle des noeuds   ///
877         //////////////////////////////////////////////////////////////////////////////////////
878         ///
879         /// Rénumérote le tableau temporaire tmp_ConnectivityArray en utilisant _optionnalToCanonicNodesNumbers
880         /// Le traitement est identique à la version originelle s'il n'y a pas de numérotation optionnelle
881         
882 //      if (_ptrMesh->_arePresentOptionnalNodesNumbers==1) 
883 //              {
884 //              for ( j=0; j<tmp_numberOfCells; j++) for (int k=0; k<NumberOfNodeByCell; k++) 
885 //                      ConnectivityArray[j*NumberOfNodeByCell+k]=_ptrMesh->_optionnalToCanonicNodesNumbers[tmp_ConnectivityArray[j*(NumberOfNodeByCell+multi)+k]] ;
886 //              }
887 //      else
888 //              {
889 //              for ( j=0; j<tmp_numberOfCells; j++) for (int k=0; k<NumberOfNodeByCell; k++) 
890 //                      ConnectivityArray[j*NumberOfNodeByCell+k]=tmp_ConnectivityArray[j*(NumberOfNodeByCell+multi)+k] ;
891 //              }
892         
893         //////////////////////////////////////////////////////////////////////////////////////
894         
895         
896           delete[] tmp_ConnectivityArray;
897   
898         }
899
900         Connectivity->_nodal = new MEDSKYLINEARRAY(Connectivity->_count[Connectivity->_numberOfTypes]-1,
901                                                    size,
902                                                    NodalIndex,
903                                                    NodalValue) ; 
904         delete[] NodalIndex;
905         delete[] NodalValue;
906         
907       } // end of bloc to read CELL
908
909       delete[] tmp_cells_count; 
910
911
912
913       // Get Face if any
914       // ===============
915      
916       if (numberOfFacesTypes!=0) {
917
918         // Create a CONNECTIVITY constituent to put in the top level CONNECTIVITY recursive class
919         CONNECTIVITY * constituent = new CONNECTIVITY(numberOfFacesTypes,MED_EN::MED_FACE) ;
920         constituent->_entityDimension = 2 ;
921         constituent->_count[0]=1 ;
922
923         // In order to create the MEDSKYLINEARRAY of the constituent object we need :
924         // 1:
925         // To initialize the _count array of the constituent object (containning cumulated face count by geometric type)
926         // _count[0]=1 and _count[_numberOfTypes] give the size of NodalIndex
927         // 2:
928         // To calculate the total number of face nodes whatever the geometric type is.
929         // The result is the size of the array containning all the nodes : NodalValue
930         // 3 :
931         // To calculate the starting indexes of the different face types in NodalValue, 
932         // this is the NodalIndex array.
933         
934         int size       = 0 ; 
935         int typeNumber = 1 ;
936         int i;
937         for ( i=1; i < MED_NBR_GEOMETRIE_MAILLE; i++)  { // no point1 cell type (?)
938           if (tmpFaceCount[i]>0) {
939             
940             constituent->_count[typeNumber] = constituent->_count[typeNumber-1] + tmpFaceCount[i];
941             CELLMODEL t( (MED_EN::medGeometryElement) MED_MESH_DRIVER::all_cell_type[i]) ;
942             constituent->_type[typeNumber-1]=t ;
943             
944             constituent->_geometricTypes[typeNumber-1]=( MED_EN::medGeometryElement) MED_MESH_DRIVER::all_cell_type[i] ;
945             
946             size+=tmpFaceCount[i]*((MED_MESH_DRIVER::all_cell_type[i])%100) ;
947             typeNumber++;
948           }
949         }
950         
951         // Creation of the MEDSKYLINEARRAY
952         //constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1,size) ; 
953         //int * NodalIndex = constituent->_nodal->getIndex() ;
954         int * NodalValue = new int[size] ;
955         int * NodalIndex = new int[constituent->_count[constituent->_numberOfTypes]] ;
956         NodalIndex[0]=1 ;
957         
958         // Fill the MEDSKYLINEARRAY by reading the MED file.
959         for ( i=0; i<constituent->_numberOfTypes; i++) {
960           MED_FR::med_geometrie_element med_type = (MED_FR::med_geometrie_element) constituent->_type[i].getType() ;
961
962           int NumberOfNodeByFace = constituent->_type[i].getNumberOfNodes() ;
963           
964           // initialise NodalIndex
965           for (int j=constituent->_count[i]; j<constituent->_count[i+1];j++)
966             NodalIndex[j]=NodalIndex[j-1]+NumberOfNodeByFace ; 
967           
968           int tmp_numberOfFaces = constituent->_count[i+1]-constituent->_count[i] ;
969           // Il faut ajouter 1 pour le zero a la lecture !!!
970           // ATTENTION UNIQUEMENT POUR MED < 2.2.x
971           int * tmp_constituentArray = NULL;
972           if (version_med != "2.2") 
973             tmp_constituentArray = new int[(NumberOfNodeByFace+1)*tmp_numberOfFaces] ;
974           else {
975             tmp_constituentArray = new int[NumberOfNodeByFace*tmp_numberOfFaces] ;
976             MESSAGE(LOC<<": WE ARE USING MED2.2 so there is no +1 for calculating the size of  tmp_constituentArray !") ;
977           }
978           int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()),
979                               Connectivity->_entityDimension,tmp_constituentArray,
980                               MED_FR::MED_FULL_INTERLACE,NULL,0,MED_FR::MED_MAILLE,med_type,MED_FR::MED_NOD);
981
982           if ( err != MED_VALID) {
983             MESSAGE(LOC<<": MEDconnLire returns "<<err) ;
984             delete constituent ;
985             delete[] tmp_constituentArray;
986             delete[] tmpFaceCount;
987             delete[] tmpEdgeCount;
988             return MED_ERROR ;
989           }
990
991           int * constituentArray = NodalValue + NodalIndex[constituent->_count[i]-1]-1 ;
992           
993           // version originale sans prise en compte des numéros optionnels
994           //    
995           for (int j=0; j<tmp_numberOfFaces; j++)
996             for (int k=0; k<NumberOfNodeByFace; k++)
997               constituentArray[j*NumberOfNodeByFace+k]=tmp_constituentArray[j*(NumberOfNodeByFace+1)+k] ;
998
999         //////////////////////////////////////////////////////////////////////////////////////
1000         ///  Modification pour prise en compte de la numérotation optionnelle des noeuds   ///
1001         //////////////////////////////////////////////////////////////////////////////////////
1002         ///
1003         /// Rénumérote le tableau temporaire tmp_constituentArray en utilisant _optionnalToCanonicNodesNumbers
1004         /// Le traitement est identique à la version originelle s'il n'y a pas de numérotation optionnelle
1005         
1006 //      if (_ptrMesh->_arePresentOptionnalNodesNumbers) 
1007 //              {
1008 //              for (int j=0; j<tmp_numberOfFaces; j++) for (int k=0; k<NumberOfNodeByFace; k++)
1009 //                      constituentArray[j*NumberOfNodeByFace+k]=_ptrMesh->_optionnalToCanonicNodesNumbers[tmp_constituentArray[j*(NumberOfNodeByFace+1)+k]] ;
1010 //              }
1011 //      else
1012 //              {
1013 //              for (int j=0; j<tmp_numberOfFaces; j++) for (int k=0; k<NumberOfNodeByFace; k++)
1014 //                      constituentArray[j*NumberOfNodeByFace+k]=tmp_constituentArray[j*(NumberOfNodeByFace+1)+k] ;
1015 //              }
1016         
1017         //////////////////////////////////////////////////////////////////////////////////////
1018           
1019           delete[] tmp_constituentArray;
1020         }
1021         
1022         constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1,
1023                                                   size,
1024                                                   NodalIndex,
1025                                                   NodalValue) ;
1026         delete[] NodalIndex ;
1027         delete[] NodalValue ;
1028
1029         Connectivity->_constituent = constituent ;
1030       }
1031
1032       delete[] tmpFaceCount;
1033
1034       // get Edge if any
1035       // ===============
1036       if (numberOfEdgesTypes!=0) {
1037         CONNECTIVITY * constituent = new CONNECTIVITY(numberOfEdgesTypes,MED_EDGE) ;
1038         constituent->_entityDimension = 1 ;
1039         constituent->_count[0]=1 ;
1040
1041         int size = 0 ; 
1042         int typeNumber=1 ;
1043         // if you declare a variable <i> in two <for> initialization statement, 
1044         // compiler gcc2.95.3 says nothing but there are two <i> variables in the same block 
1045         //and the value you get in the common block seems to be the value of the first variable !
1046         int i; 
1047
1048         for ( i=1; i<MED_NBR_GEOMETRIE_MAILLE; i++)  { // no point1 cell type (?)
1049           if (tmpEdgeCount[i]>0) {
1050             
1051             constituent->_count[typeNumber]=constituent->_count[typeNumber-1]+tmpEdgeCount[i];
1052             CELLMODEL t( (MED_EN::medGeometryElement) MED_MESH_DRIVER::all_cell_type[i]) ;
1053             constituent->_type[typeNumber-1]=t ;
1054             
1055             constituent->_geometricTypes[typeNumber-1]=( MED_EN::medGeometryElement) MED_MESH_DRIVER::all_cell_type[i] ;
1056             
1057             size+=tmpEdgeCount[i]*((MED_MESH_DRIVER::all_cell_type[i])%100) ;
1058             typeNumber++;
1059           }
1060         }
1061         
1062         // Creation of the MEDSKYLINEARRAY
1063         //constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1,size) ; 
1064         //int * NodalIndex = constituent->_nodal->getIndex() ;
1065         int * NodalValue = new int[size] ;
1066         int * NodalIndex = new int[constituent->_count[constituent->_numberOfTypes]] ;
1067         NodalIndex[0]=1 ;
1068         
1069         // Fill the MEDSKYLINEARRAY by reading the MED file.
1070         for ( i=0; i<constituent->_numberOfTypes; i++) {
1071           MED_FR::med_geometrie_element med_type = (MED_FR::med_geometrie_element) constituent->_type[i].getType() ;
1072
1073           int NumberOfNodeByEdge = constituent->_type[i].getNumberOfNodes() ;
1074           
1075           // initialise index
1076           for (int j=constituent->_count[i]; j<constituent->_count[i+1];j++)
1077             NodalIndex[j]=NodalIndex[j-1]+NumberOfNodeByEdge ; 
1078           
1079           int tmp_numberOfEdges = constituent->_count[i+1]-constituent->_count[i] ;
1080           // Il faut ajouter 1 pour le zero a la lecture !!!
1081
1082           // ATTENTION UNIQUEMENT POUR MED < 2.2.x
1083           int * tmp_constituentArray = NULL;
1084           if (version_med != "2.2") 
1085             tmp_constituentArray = new int[(NumberOfNodeByEdge+1)*tmp_numberOfEdges] ;
1086           else {
1087             tmp_constituentArray = new int[NumberOfNodeByEdge*tmp_numberOfEdges] ;
1088             MESSAGE(LOC<<": WE ARE USING MED2.2 so there is no +1 for calculating the size of  tmp_constituentArray !") ;
1089           }
1090           
1091           int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()),
1092                               _ptrMesh->_spaceDimension,tmp_constituentArray,
1093                               MED_FR::MED_FULL_INTERLACE,NULL,0,MED_FR::MED_MAILLE,med_type,MED_FR::MED_NOD);
1094           if ( err != MED_VALID) {
1095             MESSAGE(LOC<<": MEDconnLire returns "<<err) ;
1096             delete constituent ;
1097             delete[] tmp_constituentArray;
1098             delete[] tmpEdgeCount;
1099             return MED_ERROR ;
1100           }
1101
1102           int * constituentArray = NodalValue + NodalIndex[constituent->_count[i]-1]-1 ;
1103           
1104           // version originale sans prise en compte des numéros optionnels      
1105           //
1106           for (int j=0; j<tmp_numberOfEdges; j++)
1107             for (int k=0; k<NumberOfNodeByEdge; k++)
1108               constituentArray[j*NumberOfNodeByEdge+k]=tmp_constituentArray[j*(NumberOfNodeByEdge+1)+k] ;
1109
1110         //////////////////////////////////////////////////////////////////////////////////////
1111         ///  Modification pour prise en compte de la numérotation optionnelle des noeuds   ///
1112         //////////////////////////////////////////////////////////////////////////////////////
1113         ///
1114         /// Rénumérote le tableau temporaire tmp_constituentArray en utilisant _optionnalToCanonicNodesNumbers
1115         /// Le traitement est identique à la version originelle s'il n'y a pas de numérotation optionnelle
1116         
1117 //      if (_ptrMesh->_arePresentOptionnalNodesNumbers) 
1118 //              {
1119 //              for (int j=0; j<tmp_numberOfEdges; j++) for (int k=0; k<NumberOfNodeByEdge; k++)
1120 //                      constituentArray[j*NumberOfNodeByEdge+k]=_ptrMesh->_optionnalToCanonicNodesNumbers[tmp_constituentArray[j*(NumberOfNodeByEdge+1)+k]] ;
1121 //              }
1122 //      else
1123 //              {
1124 //              for (int j=0; j<tmp_numberOfEdges; j++) for (int k=0; k<NumberOfNodeByEdge; k++)
1125 //                      constituentArray[j*NumberOfNodeByEdge+k]=tmp_constituentArray[j*(NumberOfNodeByEdge+1)+k] ;
1126 //              }
1127         
1128         //////////////////////////////////////////////////////////////////////////////////////
1129
1130           delete[] tmp_constituentArray;
1131         }
1132
1133         constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1,
1134                                                   size,
1135                                                   NodalIndex,
1136                                                   NodalValue) ;
1137
1138         delete[] NodalIndex ;
1139         delete[] NodalValue ;
1140
1141         if (Connectivity->_entityDimension == 3) {
1142           if (Connectivity->_constituent==NULL)
1143             throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Edges are defined but there are no Faces !"));
1144           Connectivity->_constituent->_constituent = constituent ;
1145         } else 
1146           Connectivity->_constituent = constituent ;
1147       }
1148
1149       delete[] tmpEdgeCount; 
1150       
1151       return MED_VALID;
1152     }
1153
1154   return MED_ERROR;
1155 }
1156
1157 int MED_MESH_RDONLY_DRIVER::getDescendingConnectivity(CONNECTIVITY * Connectivity) 
1158 {
1159   const char * LOC = "MED_MESH_RDONLY_DRIVER::getDescendingConnectivity : " ;
1160   if (_status==MED_OPENED)
1161     {
1162       MESSAGE(LOC<<"call on the object " << Connectivity);
1163       MESSAGE(LOC<<"Not yet implemented !");
1164     }
1165   return MED_ERROR;
1166 }
1167
1168 //  int  MED_MESH_RDONLY_DRIVER::getElementFamilies(CONNECTIVITY * Connectivity)
1169 //  {
1170 //    int err = 0 ;
1171 //    int NumberOfTypes = Connectivity->_numberOfTypes ;
1172 //    int * Count = Connectivity->_count ;
1173 //    medGeometryElement * GeometricTypes= Connectivity->_geometricTypes ;
1174 //    int ** tmp_array = new int*[NumberOfTypes] ;
1175 //    for (int i=0; i<NumberOfTypes; i++) 
1176 //      tmp_array[i]=NULL ;
1177 //    for (int i=0; i<NumberOfTypes; i++) {
1178 //      int NumberOfElements = Count[i+1]-Count[i] ;
1179 //      int * tmp_families_number = new int[NumberOfElements] ;
1180 //      err = MEDfamLire(_medIdt,const_cast <char*> (_ptrMesh->_name.c_str()),
1181 //                   tmp_families_number,NumberOfElements,
1182 //                   Connectivity->_entity,GeometricTypes[i]);
1183 //      tmp_array[i]=tmp_families_number ;
1184 //      if (err != MED_VALID) {
1185 //        for (int j=0; j<NumberOfTypes; j++)
1186 //      if (tmp_array[j] != NULL)
1187 //        delete[] tmp_array[j] ;
1188 //        delete[] tmp_array ;
1189 //        throw MEDEXCEPTION("MED_MESH_RDONLY_DRIVER::getElementFamilies : No Family in element GeometricTypes[i]");
1190 //      }
1191 //    }
1192   
1193 //    if (Connectivity->_entity == MED_CELL)
1194 //      _ptrMesh->_MEDArrayCellFamily = tmp_array ;
1195 //    else if (Connectivity->_entity == MED_FACE)
1196 //      _ptrMesh->_MEDArrayFaceFamily = tmp_array ;
1197 //    else if (Connectivity->_entity == MED_EDGE)
1198 //      _ptrMesh->_MEDArrayEdgeFamily = tmp_array ;
1199   
1200 //    return MED_VALID ;
1201 //  }
1202
1203 int  MED_MESH_RDONLY_DRIVER::getFAMILY() 
1204 {
1205   const char * LOC = "MED_MESH_RDONLY_DRIVER::getFAMILY() : " ;
1206   BEGIN_OF(LOC);
1207
1208   if (_status==MED_OPENED)
1209     {
1210       int err = 0 ;
1211
1212       int * MEDArrayNodeFamily = NULL ;
1213       int ** MEDArrayCellFamily = NULL ;
1214       int ** MEDArrayFaceFamily = NULL ;
1215       int ** MEDArrayEdgeFamily = NULL ;
1216
1217 //     if ( !_ptrMesh->getIsAGrid() )
1218 //       {
1219     // read number :
1220     // NODE :
1221       MEDArrayNodeFamily = new int[_ptrMesh->getNumberOfNodes()] ;
1222
1223       err = getNodesFamiliesNumber(MEDArrayNodeFamily) ;
1224       // error only if (_status!=MED_OPENED), other case exeception !
1225       // CELL
1226
1227       MESSAGE(LOC << "error returned from getNodesFamiliesNumber " << err);
1228
1229       MEDArrayCellFamily = new (int*)[_ptrMesh->getNumberOfTypes(MED_CELL)] ;
1230       // ET SI IL N'Y A PAS DE CELLS ?
1231
1232       const medGeometryElement * myTypes = _ptrMesh->getTypes(MED_CELL);
1233       for (int i=0;i<_ptrMesh->getNumberOfTypes(MED_CELL);i++)
1234         MEDArrayCellFamily[i] = new
1235           int[_ptrMesh->getNumberOfElements(MED_CELL,myTypes[i])] ;
1236
1237       err = getCellsFamiliesNumber(MEDArrayCellFamily,
1238                                    _ptrMesh->_connectivity) ;
1239
1240       MESSAGE(LOC << "error returned from getCellsFamiliesNumber for Cells " << err);
1241
1242     if (_ptrMesh->_connectivity->_constituent != NULL)
1243       {
1244         if (_ptrMesh->_connectivity->_constituent->_entity == MED_EN::MED_FACE)
1245           {
1246             // FACE
1247             MEDArrayFaceFamily = new
1248               (int*)[_ptrMesh->getNumberOfTypes(MED_FACE)] ;
1249
1250             myTypes = _ptrMesh->getTypes(MED_FACE);
1251             for (int i=0;i<_ptrMesh->getNumberOfTypes(MED_FACE);i++)
1252               MEDArrayFaceFamily[i] = new
1253                 int[_ptrMesh->getNumberOfElements(MED_FACE,myTypes[i])] ;
1254         
1255             err =
1256               getCellsFamiliesNumber(MEDArrayFaceFamily,
1257                                      _ptrMesh->_connectivity->_constituent) ;
1258
1259             MESSAGE(LOC << "error returned from getCellsFamiliesNumber for Faces " << err);
1260           }
1261         else
1262           {
1263             // EDGE in 2D
1264             MEDArrayEdgeFamily = new
1265               (int*)[_ptrMesh->getNumberOfTypes(MED_EDGE)] ;
1266
1267             myTypes = _ptrMesh->getTypes(MED_EDGE);
1268             for (int i=0;i<_ptrMesh->getNumberOfTypes(MED_EDGE);i++)
1269               MEDArrayEdgeFamily[i] = new
1270                 int[_ptrMesh->getNumberOfElements(MED_EDGE,myTypes[i])] ;
1271
1272             err =
1273               getCellsFamiliesNumber(MEDArrayEdgeFamily,
1274                                      _ptrMesh->_connectivity->_constituent) ;
1275           
1276             MESSAGE(LOC << "error returned from getCellsFamiliesNumber for Edges in 2D " << err);
1277           }
1278         // EDGE in 3D
1279         if (_ptrMesh->_connectivity->_constituent->_constituent != NULL)
1280           {
1281             MEDArrayEdgeFamily = new
1282               (int*)[_ptrMesh->getNumberOfTypes(MED_EDGE)] ;
1283
1284             myTypes = _ptrMesh->getTypes(MED_EDGE);
1285             for (int i=0;i<_ptrMesh->getNumberOfTypes(MED_EDGE);i++)
1286               MEDArrayEdgeFamily[i] = new
1287                 int[_ptrMesh->getNumberOfElements(MED_EDGE,myTypes[i])] ;
1288
1289             err =
1290               getCellsFamiliesNumber(MEDArrayEdgeFamily,
1291                                      _ptrMesh->_connectivity->_constituent->_constituent);
1292             // we are in 3D !
1293         
1294             MESSAGE(LOC << "error returned from getCellsFamiliesNumber for Edges in 3D " << err);
1295
1296           }
1297       }
1298 //       }
1299 //     else
1300 //       {
1301 //      // node 
1302 //      int NumberOfNodes =  _ptrMesh->getNumberOfNodes() ;
1303 //      MEDArrayNodeFamily = new int[ NumberOfNodes ];
1304 //      err = MED_FR::MEDfamGridLire (_medIdt,
1305 //                                    const_cast <char *> (_ptrMesh->_name.c_str()),
1306 //                                    MEDArrayNodeFamily,
1307 //                                    NumberOfNodes,
1308 //                                    MED_FR::MED_NOEUD);
1309
1310 //      // what about cell face and edge ?
1311 //       }
1312
1313     // Creation of the families
1314 //     int NumberOfFamilies = MEDnFam(_medIdt,const_cast <char *> (_meshName.c_str()),0,MED_FR::MED_FAMILLE) ;
1315
1316     int NumberOfFamilies = MED_FR::MEDnFam(_medIdt, const_cast <char *>
1317                                            (_meshName.c_str())) ;
1318
1319     if ( NumberOfFamilies < 1 ) // at least family 0 must exist 
1320       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"There is no FAMILY, FAMILY 0 must exists" ));
1321
1322     SCRUTE(NumberOfFamilies);
1323
1324     vector<FAMILY*> &NodeFamilyVector = _ptrMesh->_familyNode ;
1325     vector<FAMILY*> &CellFamilyVector = _ptrMesh->_familyCell ;
1326     vector<FAMILY*> &FaceFamilyVector = _ptrMesh->_familyFace ;
1327     vector<FAMILY*> &EdgeFamilyVector = _ptrMesh->_familyEdge ;
1328
1329     int numberOfNodesFamilies = 0 ;
1330     int numberOfCellsFamilies = 0 ;
1331     int numberOfFacesFamilies = 0 ;
1332     int numberOfEdgesFamilies = 0 ;
1333
1334     for (int i=0;i<NumberOfFamilies;i++)
1335       {
1336         // int NumberOfAttributes = MEDnFam(_medIdt,const_cast <char *>
1337         //       (_meshName.c_str()),i+1,MED_FR::MED_ATTR) ;
1338
1339         int NumberOfAttributes = MED_FR::MEDnAttribut(_medIdt,
1340                                                       const_cast <char *>
1341                                                       (_meshName.c_str()),
1342                                                       (i+1));
1343
1344         if (NumberOfAttributes < 0) 
1345           throw MEDEXCEPTION("MED_MESH_RDONLY_DRIVER::getFAMILY() : NumberOfAttributes" );
1346     
1347         // int NumberOfGroups = MEDnFam(_medIdt,const_cast <char *>
1348         //    (_meshName.c_str()),i+1,MED_FR::MED_GROUPE) ;
1349
1350         int NumberOfGroups = MED_FR::MEDnGroupe(_medIdt, const_cast <char *>
1351                                                 (_meshName.c_str()),(i+1)) ;
1352
1353         if (NumberOfGroups < 0)
1354           throw MEDEXCEPTION("MED_MESH_RDONLY_DRIVER::getFAMILY() : NumberOfGroups" );
1355       
1356         int FamilyIdentifier ;
1357         string FamilyName(MED_TAILLE_NOM,'\0');
1358         int *  AttributesIdentifier = new int[NumberOfAttributes] ;
1359         int *  AttributesValues     = new int[NumberOfAttributes] ;
1360         string AttributesDescription(MED_TAILLE_DESC*NumberOfAttributes,' ') ;
1361         string GroupsNames(MED_TAILLE_LNOM*NumberOfGroups+1,'\0') ;
1362         err = MED_FR::MEDfamInfo(_medIdt,const_cast <char *>
1363                                  (_meshName.c_str()),
1364                                  (i+1),const_cast <char *>
1365                                  (FamilyName.c_str()), &FamilyIdentifier,
1366                                  AttributesIdentifier,AttributesValues,
1367                                  const_cast <char *>
1368                                  (AttributesDescription.c_str()),
1369                                  &NumberOfAttributes, const_cast <char *>
1370                                  (GroupsNames.c_str()),&NumberOfGroups);
1371
1372
1373         SCRUTE(GroupsNames);
1374         SCRUTE(FamilyName);
1375         SCRUTE(err);
1376         SCRUTE(i);
1377
1378         if (err != MED_VALID)
1379           throw MEDEXCEPTION("MED_MESH_RDONLY_DRIVER::getFAMILY() : ERROR when get FAMILY informations" );
1380
1381         if (FamilyIdentifier != 0 )
1382           {
1383             FAMILY * Family = new FAMILY(_ptrMesh,FamilyIdentifier,FamilyName,
1384                                          NumberOfAttributes,
1385                                          AttributesIdentifier,
1386                                          AttributesValues,
1387                                          AttributesDescription,
1388                                          NumberOfGroups,GroupsNames,
1389                                          MEDArrayNodeFamily,
1390                                          MEDArrayCellFamily,
1391                                          MEDArrayFaceFamily,
1392                                          MEDArrayEdgeFamily) ;
1393
1394             // All good ?
1395             // if nothing found, delete Family
1396
1397
1398             //MESSAGE(LOC << " Well is that OK now ?? " << (*Family));
1399
1400             if (Family->getNumberOfTypes() == 0)
1401               {
1402                 MESSAGE(LOC<<"Nothing found for family "<<FamilyName<<
1403                         " : skip");
1404                 delete Family;
1405               }
1406             else
1407               switch (Family->getEntity())
1408                 {
1409                 case MED_EN::MED_NODE :
1410                   NodeFamilyVector.push_back(Family) ;
1411                   numberOfNodesFamilies++ ;
1412                   break ;
1413                 case MED_EN::MED_CELL :
1414                   CellFamilyVector.push_back(Family) ;
1415                   numberOfCellsFamilies++ ;
1416                   break ;
1417                 case MED_EN::MED_FACE :
1418                   FaceFamilyVector.push_back(Family) ;
1419                   numberOfFacesFamilies++ ;
1420                   break ;
1421                 case MED_EN::MED_EDGE :
1422                   EdgeFamilyVector.push_back(Family) ;
1423                   numberOfEdgesFamilies++ ;
1424                   break ;
1425                 }
1426             //  MESSAGE(LOC << (*Family));
1427           }
1428
1429         delete [] AttributesIdentifier ;
1430         delete [] AttributesValues ;
1431       }
1432
1433     if (MEDArrayNodeFamily != NULL)
1434       delete[] MEDArrayNodeFamily ;
1435
1436     if (MEDArrayCellFamily != NULL)
1437       {
1438         for (int i=0;i<_ptrMesh->getNumberOfTypes(MED_CELL);i++)
1439           delete[] MEDArrayCellFamily[i] ;
1440         delete[] MEDArrayCellFamily ;
1441       }
1442
1443     if (MEDArrayFaceFamily != NULL)
1444       {
1445         for (int i=0;i<_ptrMesh->getNumberOfTypes(MED_FACE);i++)
1446           delete[] MEDArrayFaceFamily[i] ;
1447         delete[] MEDArrayFaceFamily ;
1448       }
1449
1450     if (MEDArrayEdgeFamily != NULL)
1451       {
1452         for (int i=0;i<_ptrMesh->getNumberOfTypes(MED_EDGE);i++)
1453           delete[] MEDArrayEdgeFamily[i] ;
1454         delete[] MEDArrayEdgeFamily ;
1455       }
1456
1457     END_OF(LOC);
1458     return MED_VALID ;
1459     }
1460
1461   return MED_ERROR;
1462 }
1463
1464 int  MED_MESH_RDONLY_DRIVER::getNodesFamiliesNumber(int * MEDArrayNodeFamily) 
1465 {
1466   const char * LOC = "MED_MESH_RDONLY_DRIVER::getNodesFamiliesNumber() : " ;
1467
1468   BEGIN_OF(LOC);
1469
1470   if (_status==MED_OPENED)
1471     {
1472       int err = 0 ;
1473
1474       err = MEDfamLire(_medIdt, const_cast <char *>
1475                        (_ptrMesh->_name.c_str()), MEDArrayNodeFamily,
1476                        _ptrMesh->getNumberOfNodes(), MED_FR::MED_NOEUD,
1477                        (enum MED_FR::med_geometrie_element) MED_NONE);
1478
1479       if ( err != MED_VALID)
1480         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "There is no family for the |"<< _ptrMesh->getNumberOfNodes() << "| nodes in mesh |" << _ptrMesh->_name.c_str() << "|"));
1481
1482       END_OF(LOC);
1483       return MED_VALID;
1484     }
1485
1486   return MED_ERROR;
1487 }
1488
1489 int  MED_MESH_RDONLY_DRIVER::getCellsFamiliesNumber(int **MEDArrayFamily,CONNECTIVITY *Connectivity) 
1490 {
1491   const char * LOC = "MED_MESH_RDONLY_DRIVER::getCellsFamiliesNumber " ;
1492
1493   BEGIN_OF(LOC);
1494
1495   if (_status==MED_OPENED)
1496     {
1497       int i, err = 0 ;
1498
1499       SCRUTE(Connectivity->_numberOfTypes);
1500
1501       for (i=0;i<Connectivity->_numberOfTypes;i++)
1502         {
1503           int NumberOfCell = Connectivity->_count[i+1]-Connectivity->_count[i];
1504
1505           SCRUTE(NumberOfCell);
1506
1507           err=MEDfamLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()),
1508                          MEDArrayFamily[i],NumberOfCell,
1509                          (MED_FR::med_entite_maillage) Connectivity->_entity,
1510                          (MED_FR::med_geometrie_element)
1511                          Connectivity->_geometricTypes[i]);
1512
1513           // provisoire : si les faces ou les aretes sont des mailles !!!
1514           if (err != MED_VALID)
1515             {
1516               MESSAGE(LOC<<"search face/edge family on cell !!!");
1517               err=MEDfamLire(_medIdt,const_cast <char *>
1518                              (_ptrMesh->_name.c_str()),
1519                              MEDArrayFamily[i],NumberOfCell,
1520                              MED_FR::MED_MAILLE,
1521                              (MED_FR::med_geometrie_element)
1522                              Connectivity->_geometricTypes[i]);
1523             }
1524
1525           if (err != MED_VALID) 
1526             throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Family not found for entity "<<Connectivity->_entity<<" and geometric type "<<Connectivity->_geometricTypes[i]));
1527         }
1528       return MED_VALID;
1529     }
1530   return MED_ERROR;  
1531 }
1532
1533 void MED_MESH_RDONLY_DRIVER::buildAllGroups(vector<GROUP*> & Groups, vector<FAMILY*> & Families) 
1534 {
1535   const char * LOC = "MED_MESH_RDONLY_DRIVER::buildAllGroups " ;
1536   BEGIN_OF(LOC);
1537
1538   int numberOfFamilies = Families.size() ;
1539   //SCRUTE(numberOfFamilies);
1540   map< string,list<FAMILY*> > groupsNames ;
1541   for(int i=0; i<numberOfFamilies; i++) {
1542     FAMILY * myFamily = Families[i] ;
1543     int numberOfGroups_ = myFamily->getNumberOfGroups();
1544     //SCRUTE(i);
1545     //SCRUTE(numberOfGroups_);
1546     for (int j=0; j<numberOfGroups_; j++) {
1547       //SCRUTE(j);
1548       //SCRUTE(myFamily->getGroupName(j+1));
1549       groupsNames[myFamily->getGroupName(j+1)].push_back(myFamily);
1550     }
1551   }
1552   int numberOfGroups = groupsNames.size() ;
1553   SCRUTE(numberOfGroups);
1554   Groups.resize(numberOfGroups);
1555   map< string,list<FAMILY*> >::const_iterator currentGroup ;
1556   int it = 0 ;
1557   for(currentGroup=groupsNames.begin();currentGroup!=groupsNames.end();currentGroup++) {
1558     GROUP * myGroup = new GROUP((*currentGroup).first,(*currentGroup).second) ;
1559 //     GROUP * myGroup = new GROUP() ;
1560 //     myGroup->setName((*currentGroup).first);
1561 //     SCRUTE(myGroup->getName());
1562 //     //myGroup->setMesh(_ptrMesh);
1563 //     myGroup->init((*currentGroup).second);
1564     Groups[it]=myGroup;
1565     //SCRUTE(it);
1566     it++;
1567   }
1568
1569   END_OF(LOC);
1570 }
1571
1572 void MED_MESH_RDONLY_DRIVER::updateFamily()
1573 {
1574   const char * LOC = "MED_MESH_RDONLY_DRIVER::updateFamily() " ;
1575   BEGIN_OF(LOC);
1576
1577   // we need to update family on constituent if we have constituent, but no 
1578   // descending connectivity, so, we must calculate all constituent and
1579   // numbering correctly family !
1580   _ptrMesh->_connectivity->updateFamily(_ptrMesh->_familyFace) ; // in 2d, do nothing
1581   _ptrMesh->_connectivity->updateFamily(_ptrMesh->_familyEdge) ; // in 3d, do nothing
1582
1583   END_OF(LOC);
1584 }
1585
1586
1587 void MED_MESH_RDONLY_DRIVER::write( void ) const
1588   throw (MEDEXCEPTION)
1589 {
1590   throw MEDEXCEPTION("MED_MESH_RDONLY_DRIVER::write : Can't write with a RDONLY driver !");
1591 }
1592
1593 /*--------------------- WRONLY PART -------------------------------*/
1594
1595 MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER():MED_MESH_DRIVER()
1596 {
1597 }
1598   
1599 MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER(const string & fileName,
1600                                                MESH * ptrMesh):
1601   MED_MESH_DRIVER(fileName,ptrMesh,MED_WRONLY)
1602 {
1603   MESSAGE("MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
1604 }
1605
1606 MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER(const MED_MESH_WRONLY_DRIVER & driver): 
1607   MED_MESH_DRIVER(driver)
1608 {
1609 }
1610
1611 MED_MESH_WRONLY_DRIVER::~MED_MESH_WRONLY_DRIVER()
1612 {
1613   //MESSAGE("MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed");
1614 }
1615
1616 GENDRIVER * MED_MESH_WRONLY_DRIVER::copy(void) const
1617 {
1618   return new MED_MESH_WRONLY_DRIVER(*this);
1619 }
1620
1621 void MED_MESH_WRONLY_DRIVER::read (void)
1622   throw (MEDEXCEPTION)
1623 {
1624   throw MEDEXCEPTION("MED_MESH_WRONLY_DRIVER::read : Can't read with a WRONLY driver !");
1625 }
1626
1627 void MED_MESH_WRONLY_DRIVER::write(void) const
1628   throw (MEDEXCEPTION)
1629
1630   const char * LOC = "void MED_MESH_WRONLY_DRIVER::write(void) const : ";
1631   BEGIN_OF(LOC);
1632
1633   // we must first create mesh !!
1634   MESSAGE(LOC << "MeshName : |" << _meshName << "| FileName : |"<<_fileName<<"| MedIdt : | "<< _medIdt << "|");
1635
1636   if (_status!=MED_OPENED)
1637     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "File "<<_fileName<<" is not open. Open it before write !"));
1638
1639   if (_ptrMesh->getIsAGrid())
1640   {
1641     if ( writeGRID() != MED_VALID )
1642       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeGRID()"  )) ;
1643   }
1644   else
1645   {
1646     if (writeCoordinates()!=MED_VALID)
1647       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeCoordinates()"  )) ;
1648
1649     if (writeConnectivities(MED_EN::MED_CELL)!=MED_VALID)
1650       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeConnectivities(MED_CELL)"  )) ;
1651     if (writeConnectivities(MED_EN::MED_FACE)!=MED_VALID)
1652       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeConnectivities(MED_FACE)"  )) ;
1653     if (writeConnectivities(MED_EN::MED_EDGE)!=MED_VALID)
1654       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeConnectivities(MED_EDGE)"  )) ;
1655   }
1656
1657   if (writeFamilyNumbers() !=MED_VALID)
1658     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilyNumbers()"  )) ;
1659   
1660
1661   // well we must first write zero family :
1662   if (_status==MED_OPENED) {
1663     int err ;
1664     // test if the family already exists (HDF trick waiting a MED evolution to be replaced)
1665     string dataGroupFam = "/ENS_MAA/"+_meshName+"/FAS/FAMILLE_0/";  
1666     MESSAGE("|"<<dataGroupFam<<"|");
1667     err =_MEDdatagroupOuvrir(_medIdt,const_cast <char *> (dataGroupFam.c_str()) );
1668     if ( err < MED_VALID ) {
1669       SCRUTE(err);
1670       
1671       err = MED_FR::MEDfamCr( _medIdt,
1672                               const_cast <char *> ( _meshName.c_str() ),
1673                               "FAMILLE_0", 0,
1674                               (int*)NULL, (int*)NULL, (char*)NULL, 0,
1675                               (char*)NULL, 0);
1676       
1677       if ( err != MED_VALID) 
1678         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't create family |FAMILLE_0| with identifier |0| groups names || and  attributes descriptions ||")) ;
1679     }
1680     else
1681       _MEDdatagroupFermer(_medIdt);
1682      
1683   }
1684
1685   MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyNode)");
1686   if (writeFamilies(_ptrMesh->_familyNode) !=MED_VALID)
1687     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyNode)"  )) ;
1688
1689   MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyCell)");
1690   if (writeFamilies(_ptrMesh->_familyCell) !=MED_VALID)
1691     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyCell)"  )) ;
1692
1693   MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyFace)");
1694   if (writeFamilies(_ptrMesh->_familyFace) !=MED_VALID)
1695     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyFace)"  )) ;
1696
1697   MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyEdge)");
1698   if (writeFamilies(_ptrMesh->_familyEdge) !=MED_VALID)
1699     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyEdge)"  )) ;
1700
1701   END_OF(LOC);
1702
1703
1704 //=======================================================================
1705 //function : writeGRID
1706 //purpose  : 
1707 //=======================================================================
1708
1709 int MED_MESH_WRONLY_DRIVER::writeGRID() const
1710 {
1711   const char * LOC = "MED_MESH_WRONLY_DRIVER::writeGRID() : " ;
1712   BEGIN_OF(LOC);
1713   
1714   if (_status!=MED_OPENED)
1715   {
1716     MESSAGE (LOC<<" Not open !!!");
1717     return MED_ERROR;
1718   }
1719   GRID * ptrGrid = (GRID*) _ptrMesh;
1720   
1721   MED_FR::med_err err = MED_ERROR;
1722   MED_FR::med_repere rep;
1723   string tmp_name(_ptrMesh->_spaceDimension*MED_TAILLE_PNOM,' ');
1724   string tmp_unit(_ptrMesh->_spaceDimension*MED_TAILLE_PNOM,' ');
1725
1726   // Test if the mesh <_meshName> already exists
1727   // If it doesn't exists create it
1728   // If it already exists verify if its space and mesh dimensions are the same
1729   // as <_ptrMesh->_spaceDimension>, <_ptrMesh->_meshDimension> respectively
1730   // rem : <_meshName> is the driver meshName not <ptrMesh->_meshName>
1731
1732   int spaceDimension = MED_FR::MEDdimEspaceLire(_medIdt, const_cast <char *>
1733                                                 (_meshName.c_str()) );
1734
1735   int meshDimension = MED_FR::MEDdimLire(_medIdt, const_cast <char *>
1736                                          (_meshName.c_str()) );
1737
1738   if ((spaceDimension != MED_VALID) && (meshDimension != MED_VALID))
1739     {
1740       err = MEDmaaCr(_medIdt,
1741                      const_cast <char *> (_meshName.c_str()),
1742                      _ptrMesh->_meshDimension,MED_FR::MED_STRUCTURE,
1743                      const_cast <char *> (_ptrMesh->_description.c_str()));
1744
1745     if (err != MED_VALID)
1746       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Unable to create Grid"));
1747     else 
1748       MESSAGE(LOC<<"Grid "<<_meshName<<" created in file "<<_fileName<<" !");
1749   }
1750   else if ((spaceDimension != _ptrMesh->_spaceDimension)  &&
1751            (meshDimension != _ptrMesh->_meshDimension))
1752     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Grid |" << _meshName.c_str() <<
1753                                  "| already exists in file |" << _fileName <<
1754                                  "| with space dimension |" << spaceDimension <<
1755                                  "| and mesh dimension |" << meshDimension <<
1756                                  "| but the space dimension and the mesh dimension of the mesh we want to write are respectively |"
1757                                  << _ptrMesh->_spaceDimension <<"|" <<
1758                                  _ptrMesh->_meshDimension <<"|" )) ;
1759
1760   // Recompose the <_spaceDimension> strings in 1 string 
1761   int lengthString ;
1762   string valueString ;
1763   for (int i=0;i<_ptrMesh->_spaceDimension;i++) {
1764     SCRUTE(i);
1765     valueString = _ptrMesh->_coordinate->_coordinateName[i] ;
1766     lengthString = (MED_TAILLE_PNOM<valueString.size())?MED_TAILLE_PNOM:valueString.size() ;
1767     tmp_name.replace(i*MED_TAILLE_PNOM,i*MED_TAILLE_PNOM+lengthString,valueString,0,lengthString);
1768     valueString = _ptrMesh->_coordinate->_coordinateUnit[i];
1769     lengthString = (MED_TAILLE_PNOM<valueString.size())?MED_TAILLE_PNOM:valueString.size() ;
1770     tmp_unit.replace(i*MED_TAILLE_PNOM,i*MED_TAILLE_PNOM+lengthString,valueString,0,lengthString);
1771   }
1772
1773   // Pourquoi le stocker sous forme de chaîne ?
1774   const string & coordinateSystem = _ptrMesh->_coordinate->_coordinateSystem;
1775   if      (coordinateSystem  == "CARTESIAN") 
1776     rep = MED_FR::MED_CART;
1777   else if ( coordinateSystem == "CYLINDRICAL")
1778     rep = MED_FR::MED_CYL;
1779   else if ( coordinateSystem == "SPHERICAL" )
1780     rep = MED_FR::MED_SPHER;
1781   else
1782     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Grid |" << _meshName.c_str() <<
1783                                  "| doesn't have a valid coordinate system : |" 
1784                                  << _ptrMesh->_coordinate->_coordinateSystem
1785                                  << "|" )) ;  
1786
1787   int ArrayLen[] = { ptrGrid->_iArrayLength,
1788                      ptrGrid->_jArrayLength,
1789                      ptrGrid->_kArrayLength  };
1790   
1791   med_type_grille gridType = ptrGrid->getGridType();
1792
1793   // Write node coordinates for MED_BODY_FITTED grid
1794   if (gridType == MED_EN::MED_GRILLE_STANDARD)
1795     {
1796       // Write Coordinates and families
1797       double * coo = const_cast <double *>
1798         (_ptrMesh->_coordinate->getCoordinates(MED_EN::MED_FULL_INTERLACE));
1799     
1800       int* structure = new int [meshDimension];
1801
1802       for (int idim = 0; idim < meshDimension; ++idim)
1803         structure[idim] = ArrayLen [idim];
1804  
1805
1806       err = MED_FR::MEDstructureCoordEcr(_medIdt, const_cast <char *>
1807                                          (_meshName.c_str()), meshDimension,
1808                                          structure);
1809
1810       if (err != MED_VALID)
1811         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"error in writing the structure of the grid |" << _meshName.c_str()));
1812
1813       delete structure;
1814
1815       err = MEDcoordEcr(_medIdt, const_cast <char *> (_meshName.c_str()),
1816                         _ptrMesh->_spaceDimension, 
1817                         //const_cast <double *> ( _ptrMesh->_coordinate->_coordinate->get(MED_EN::MED_FULL_INTERLACE) ), 
1818                         const_cast <double *> ( _ptrMesh->_coordinate->_coordinate.get(MED_EN::MED_FULL_INTERLACE) ), 
1819                         MED_FR::MED_FULL_INTERLACE, _ptrMesh->_numberOfNodes,
1820                         //  _ptrMesh->_coordinate->_numberOfNodes
1821                         rep, const_cast <char *> (tmp_name.c_str()), 
1822                         const_cast <char *> (tmp_unit.c_str()));
1823
1824       if (err != MED_VALID) 
1825         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write coordinates of the grid |" << _meshName.c_str() << "| in file |" << _fileName
1826                                      << "| with dimension |"  << _ptrMesh->_spaceDimension <<"| and" 
1827                                      << " with units names |"  << tmp_name
1828                                      << "| and units |"       << tmp_unit
1829                                      << " |")) ;
1830     }
1831   else if ((gridType == MED_EN::MED_GRILLE_CARTESIENNE) ||
1832            (gridType == MED_EN::MED_GRILLE_POLAIRE))
1833     {
1834       // Write Arrays of Cartesian or Polar Grid
1835
1836       double * Array[] = { ptrGrid->_iArray,
1837                            ptrGrid->_jArray,
1838                            ptrGrid->_kArray };
1839
1840       for (int idim = 0; idim < _ptrMesh->_meshDimension; ++idim)
1841         {
1842           string str_name = string (tmp_name,idim*MED_TAILLE_PNOM,
1843                                     MED_TAILLE_PNOM);
1844           string str_unit = string (tmp_unit,idim*MED_TAILLE_PNOM,
1845                                     MED_TAILLE_PNOM);
1846
1847           err = MED_FR::MEDindicesCoordEcr(_medIdt, const_cast <char *>
1848                                            (_ptrMesh->_name.c_str()),
1849                                            _ptrMesh->_meshDimension,
1850                                            Array[idim], ArrayLen[idim],
1851                                            (idim+1), const_cast <char *>
1852                                            (str_name.c_str()),
1853                                            const_cast <char *>
1854                                            (str_unit.c_str()));
1855
1856           if (err != MED_VALID)
1857             throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<
1858                                          "Can't write grid coordinates for " <<
1859                                          idim << "-th dimention"));
1860         }
1861   } // end Write  Cartesian or Polar Grid
1862
1863   END_OF(LOC);
1864   return MED_VALID;
1865 }
1866
1867 //=======================================================================
1868 //function : writeCoordinates
1869 //purpose  : 
1870 //=======================================================================
1871
1872 int MED_MESH_WRONLY_DRIVER::writeCoordinates() const {
1873  
1874   const char * LOC = "int MED_MESH_WRONLY_DRIVER::writeCoordinates() const : ";
1875   BEGIN_OF(LOC);
1876
1877   MED_FR::med_err err = MED_ERROR;
1878   MED_FR::med_repere rep;
1879   string tmp_name(_ptrMesh->_spaceDimension*MED_TAILLE_PNOM,' ');
1880   string tmp_unit(_ptrMesh->_spaceDimension*MED_TAILLE_PNOM,' ');
1881     
1882   // Recompose the <_spaceDimension> strings in 1 string 
1883   int lengthString ;
1884   string valueString ;
1885   for (int i=0;i<_ptrMesh->_spaceDimension;i++) {
1886     valueString = _ptrMesh->_coordinate->_coordinateName[i] ;
1887     lengthString = (MED_TAILLE_PNOM<valueString.size())?MED_TAILLE_PNOM:valueString.size() ;
1888     tmp_name.replace(i*MED_TAILLE_PNOM,i*MED_TAILLE_PNOM+lengthString,valueString,0,lengthString);
1889     valueString = _ptrMesh->_coordinate->_coordinateUnit[i];
1890     lengthString = (MED_TAILLE_PNOM<valueString.size())?MED_TAILLE_PNOM:valueString.size() ;
1891     tmp_unit.replace(i*MED_TAILLE_PNOM,i*MED_TAILLE_PNOM+lengthString,valueString,0,lengthString);
1892   }
1893
1894   // Test if the mesh <_meshName> already exists
1895   // If it doesn't exists create it
1896   // If it already exists verify if its space and mesh dimensions are the same
1897   // as <_ptrMesh->_spaceDimension>, <_ptrMesh->_meshDimension> respectively
1898   // rem : <_meshName> is the driver meshName not <ptrMesh->_meshName>
1899
1900   int spaceDimension = MED_FR::MEDdimEspaceLire(_medIdt, const_cast <char *>
1901                                                 (_meshName.c_str()));
1902
1903   int meshDimension = MED_FR::MEDdimLire(_medIdt, const_cast <char *>
1904                                          (_meshName.c_str()) );
1905
1906   if ((spaceDimension != MED_VALID) && (meshDimension != MED_VALID))
1907     {
1908       err = MEDmaaCr(_medIdt, const_cast <char *> (_meshName.c_str()),
1909                      _ptrMesh->_meshDimension, MED_FR::MED_NON_STRUCTURE,
1910                      const_cast <char *> (_ptrMesh->_description.c_str()));
1911
1912       if (err != MED_VALID)
1913         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Unable to create Mesh : |" << _meshName << "|"));
1914       else 
1915         MESSAGE(LOC<<"Mesh "<<_meshName<<" created in file "<<_fileName<<" !");
1916     }
1917   else if ((spaceDimension != _ptrMesh->_spaceDimension)  &&
1918            (meshDimension != _ptrMesh->_meshDimension))
1919     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Mesh |" << _meshName.c_str() <<
1920                                  "| already exists in file |" << _fileName <<
1921                                  "| with space dimension |" << spaceDimension <<
1922                                  "| and mesh dimension |" << meshDimension <<
1923                                  "| but the space dimension and the mesh dimension of the mesh we want to write are respectively |"
1924                                  << _ptrMesh->_spaceDimension <<"|" <<
1925                                  _ptrMesh->_meshDimension << "|")) ;
1926     
1927   // Pourquoi le stocker sous forme de chaîne ?
1928   const string & coordinateSystem = _ptrMesh->_coordinate->_coordinateSystem;
1929   if      (coordinateSystem  == "CARTESIAN") 
1930     rep = MED_FR::MED_CART;
1931   else if ( coordinateSystem == "CYLINDRICAL")
1932     rep = MED_FR::MED_CYL;
1933   else if ( coordinateSystem == "SPHERICAL" )
1934     rep = MED_FR::MED_SPHER;
1935   else
1936     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Mesh |" << _meshName.c_str() << "| doesn't have a valid coordinate system : |" 
1937                                  << _ptrMesh->_coordinate->_coordinateSystem
1938                                  << "|" )) ;  
1939       
1940 //   err = MEDcoordEcr(_medIdt, const_cast <char *> (_meshName.c_str()),
1941 //                  _ptrMesh->_spaceDimension, 
1942 //                  //const_cast <double *> ( _ptrMesh->_coordinate->_coordinate->get(MED_EN::MED_FULL_INTERLACE) ), 
1943 //                  const_cast <double *> ( _ptrMesh->_coordinate->_coordinate.get(MED_EN::MED_FULL_INTERLACE) ), 
1944 //                  MED_FR::MED_FULL_INTERLACE, 
1945 //                  _ptrMesh->_numberOfNodes,                 //  _ptrMesh->_coordinate->_numberOfNodes
1946 //                  MED_FR::MED_LECTURE_ECRITURE,    
1947 //                  rep,
1948 //                  const_cast <char *> (tmp_name.c_str()), 
1949 //                  const_cast <char *> (tmp_unit.c_str()) 
1950 //                  );
1951
1952   err = MEDcoordEcr(_medIdt, const_cast <char *> (_meshName.c_str()),
1953                     _ptrMesh->_spaceDimension, 
1954                     //const_cast <double *> ( _ptrMesh->_coordinate->_coordinate->get(MED_EN::MED_FULL_INTERLACE) ), 
1955                     const_cast <double *> ( _ptrMesh->_coordinate->_coordinate.get(MED_EN::MED_FULL_INTERLACE) ), 
1956                     MED_FR::MED_FULL_INTERLACE, _ptrMesh->_numberOfNodes,
1957                     //  _ptrMesh->_coordinate->_numberOfNodes
1958                     rep, const_cast <char *> (tmp_name.c_str()), 
1959                     const_cast <char *> (tmp_unit.c_str()));
1960
1961   if (err<0) 
1962     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write coordinates of mesh |" << _meshName.c_str() << "| in file |" << _fileName
1963                                  << "| with dimension |"  << _ptrMesh->_spaceDimension <<"| and" 
1964                                  << " with units names |"  << tmp_name
1965                                  << "| and units |"       << tmp_unit
1966                                  << " |")) ;    
1967     
1968
1969        //////////////////////////////////////////////////////////////////////////////////////
1970        ///  Modification pour prise en compte de la numérotation optionnelle des noeuds   ///
1971        //////////////////////////////////////////////////////////////////////////////////////
1972        ///
1973        /// Ecrit les numéros optionnels des noeuds
1974        /// Le traitement est identique à la version originelle s'il n'y a pas de numérotation optionnelle
1975
1976
1977       if (_ptrMesh->_arePresentOptionnalNodesNumbers==1) {
1978         
1979         err =  MEDnumEcr(_medIdt, const_cast <char *> (_meshName.c_str()),
1980                          const_cast <med_int *> (_ptrMesh->_coordinate->getNodesNumbers() ), 
1981                          _ptrMesh->_numberOfNodes, MED_FR::MED_NOEUD,
1982                          MED_FR::med_geometrie_element(0) );
1983
1984         if (err != MED_VALID) 
1985           throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write optionnal numbers of mesh |" << 
1986                                        _meshName.c_str() << "| in file |" <<
1987                                        _fileName  << " |")) ;
1988       }
1989       //////////////////////////////////////////////////////////////////////////////////////
1990
1991   END_OF(LOC);
1992     
1993   return MED_VALID;
1994 }
1995
1996
1997
1998
1999 int MED_MESH_WRONLY_DRIVER::writeConnectivities(medEntityMesh entity) const {
2000   
2001   const char * LOC="int MED_MESH_WRONLY_DRIVER::writeConnectivities() const : ";
2002   BEGIN_OF(LOC);
2003
2004   MED_FR::med_err err;
2005   
2006   // REM SI LA METHODE EST APPELEE DIRECTEMENT ET QUE LE MAILLAGE N'EST PAS CREE IL Y A PB !
2007   // PG : IMPOSSIBLE : LA METHODE EST PRIVEE !
2008     
2009     // A FAIRE : A tester surtout dans les methodes de MESH.
2010     //    if ( _ptrMesh->_connectivity == (CONNECTIVITY *) MED_INVALID )
2011   if ( _ptrMesh->_connectivity == (CONNECTIVITY *) NULL )
2012     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The connectivity is not defined in the MESH object ")) ;
2013     
2014   if   ( _ptrMesh->existConnectivity(MED_NODAL,entity) ) { 
2015
2016     int numberOfTypes           = _ptrMesh->getNumberOfTypes (entity) ;
2017     const medGeometryElement  * types = _ptrMesh->getTypes         (entity) ;
2018     
2019     for (int i=0; i<numberOfTypes; i++) {
2020       
2021       int    numberOfElements = _ptrMesh->getNumberOfElements (entity,types[i]);
2022       const int * connectivity      = _ptrMesh->getConnectivity     (MED_EN::MED_FULL_INTERLACE, 
2023                                                                      MED_NODAL, entity, types[i]); // ?? et SI MED_NODAL n'existe pas, recalcul auto ??
2024       
2025       // Pour l'instant la class utilise le multi.....
2026       int multi = 0 ;
2027       if (entity==MED_EN::MED_CELL)
2028         if ( (types[i]/ 100) < _ptrMesh->_spaceDimension) 
2029           multi=1 ;
2030       int numberOfNodes = types[i]%100 ;
2031       int * connectivityArray = new int[numberOfElements*(numberOfNodes+multi)];
2032       
2033       // version originale sans prise en compte des numéros optionnels 
2034       //     
2035       for (int j=0 ; j<numberOfElements; j++) 
2036         {
2037           for (int k=0; k<numberOfNodes; k++)
2038             connectivityArray[j*(numberOfNodes+multi)+k]=connectivity[j*numberOfNodes+k] ;
2039
2040           if (multi>0) connectivityArray[j*(numberOfNodes+multi)+numberOfNodes]=0;
2041         }
2042       
2043       //////////////////////////////////////////////////////////////////////////////////////
2044       ///  Modification pour prise en compte de la numérotation optionnelle des noeuds   ///
2045       //////////////////////////////////////////////////////////////////////////////////////
2046       ///
2047       /// Dénumérote les sommets des mailles pour leur rendre leurs numéros optionnels
2048       /// Le traitement est identique à la version originelle s'il n'y a pas de numérotation optionnelle
2049
2050 //      if (_ptrMesh->_arePresentOptionnalNodesNumbers==1) 
2051 //              {
2052 //              const int * nodesNumbers = _ptrMesh->_coordinate->getNodesNumbers();
2053 //                      for (int j=0 ; j<numberOfElements; j++) 
2054 //                      {
2055 //                      for (int k=0; k<numberOfNodes; k++) connectivityArray[j*(numberOfNodes+multi)+k]=nodesNumbers[connectivity[j*numberOfNodes+k]-1] ;
2056 //                      if (multi>0) connectivityArray[j*(numberOfNodes+multi)+numberOfNodes]=0;
2057 //                      }
2058 //              }
2059 //      else
2060 //              {
2061 //                      for (int j=0 ; j<numberOfElements; j++) 
2062 //                      {
2063 //                      for (int k=0; k<numberOfNodes; k++) connectivityArray[j*(numberOfNodes+multi)+k]=connectivity[j*numberOfNodes+k] ;
2064 //                      if (multi>0) connectivityArray[j*(numberOfNodes+multi)+numberOfNodes]=0;
2065 //                      }
2066 //              }
2067
2068       //////////////////////////////////////////////////////////////////////////////////////
2069       
2070 //       err = MEDconnEcr( _medIdt, const_cast <char *> ( _meshName.c_str()), _ptrMesh->_spaceDimension,
2071 //                      connectivityArray, MED_FR::MED_FULL_INTERLACE , numberOfElements,
2072 //                      MED_FR::MED_LECTURE_ECRITURE,
2073 //                      (MED_FR::med_entite_maillage  ) entity, 
2074 //                      (MED_FR::med_geometrie_element) types[i], MED_FR::MED_NOD );
2075
2076           err = MEDconnEcr(_medIdt, const_cast <char *> ( _meshName.c_str()),
2077                            _ptrMesh->_spaceDimension, connectivityArray,
2078                            MED_FR::MED_FULL_INTERLACE , numberOfElements,
2079                            (MED_FR::med_entite_maillage  ) entity, 
2080                            (MED_FR::med_geometrie_element) types[i],
2081                            MED_FR::MED_NOD);
2082
2083       delete[] connectivityArray ;
2084
2085       if (err<0) // ETENDRE LES EXPLICATIONS
2086         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write connectivities of mesh |" << _meshName.c_str() << "| in file |" << _fileName
2087                                      << "| with dimension |"  << _ptrMesh->_spaceDimension <<"| and" 
2088                                      )) ;
2089     }
2090   }
2091   // Connctivity descending :
2092   if   ( _ptrMesh->existConnectivity(MED_DESCENDING,entity) ) { 
2093       
2094     int numberOfTypes           = _ptrMesh->getNumberOfTypes (entity) ;
2095     const medGeometryElement  * types = _ptrMesh->getTypes         (entity) ;
2096       
2097     for (int i=0; i<numberOfTypes; i++) {
2098         
2099       int    numberOfElements = _ptrMesh->getNumberOfElements (entity,types[i]);
2100       const int * connectivity = _ptrMesh->getConnectivity(MED_EN::MED_FULL_INTERLACE, MED_DESCENDING, entity, types[i]); 
2101       
2102       // Pour l'instant la class utilise le multi.....
2103 //       err = MED_FR::MEDconnEcr( _medIdt,
2104 //                              const_cast <char *> ( _meshName.c_str()),
2105 //                              _ptrMesh->_spaceDimension,
2106 //                              const_cast <int *> (connectivity),
2107 //                              MED_FR::MED_FULL_INTERLACE,
2108 //                              numberOfElements,
2109 //                              MED_FR::MED_LECTURE_ECRITURE,
2110 //                              (MED_FR::med_entite_maillage  ) entity, 
2111 //                              (MED_FR::med_geometrie_element) types[i],
2112 //                              MED_FR::MED_DESC );
2113
2114       err = MED_FR::MEDconnEcr(_medIdt,
2115                                const_cast <char *> ( _meshName.c_str()),
2116                                _ptrMesh->_spaceDimension,
2117                                const_cast <int *> (connectivity),
2118                                MED_FR::MED_FULL_INTERLACE,
2119                                numberOfElements,
2120                                (MED_FR::med_entite_maillage  ) entity, 
2121                                (MED_FR::med_geometrie_element) types[i],
2122                                MED_FR::MED_DESC );
2123         
2124       if (err<0) // ETENDRE LES EXPLICATIONS
2125         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write connectivities of mesh |" << _meshName.c_str() << "| in file |" << _fileName
2126                                      << "| with dimension |"  << _ptrMesh->_spaceDimension <<"| and" 
2127                                      )) ;
2128             
2129     }
2130   }
2131   END_OF(LOC);
2132   return MED_VALID;
2133 }
2134
2135 int MED_MESH_WRONLY_DRIVER::writeFamilyNumbers() const {
2136   
2137   const char * LOC="int MED_MESH_WRONLY_DRIVER::writeFamilyNumbers() const : ";
2138   BEGIN_OF(LOC);
2139
2140   MED_FR::med_err err;
2141   
2142   // SOLUTION TEMPORAIRE CAR _ptrMesh->_MEDArrayNodeFamily DOIT ETRE ENLEVER DE LA CLASSE MESH
2143
2144   { // Node related block
2145     
2146     // We build the array from the families list objects :
2147     int NumberOfNodes = _ptrMesh->getNumberOfNodes() ;
2148     int * MEDArrayNodeFamily = new int[NumberOfNodes] ;
2149     // family 0 by default
2150     for (int i=0; i<NumberOfNodes; i++)
2151       MEDArrayNodeFamily[i]=0;
2152     //vector<FAMILY*> myFamilies = _ptrMesh->getFamilies(MED_NODE);
2153     vector<FAMILY*> * myFamilies = &_ptrMesh->_familyNode;
2154     int NumberOfNodesFamilies = myFamilies->size() ;
2155     //bool ToDestroy = false;
2156     if (0 == NumberOfNodesFamilies) {
2157       //ToDestroy = true ;
2158       vector<GROUP*> myGroups = _ptrMesh->getGroups(MED_NODE);
2159       int NumberOfGroups = myGroups.size() ;
2160       // build families from groups
2161       for (int i=0; i<NumberOfGroups; i++) {
2162         SUPPORT * mySupport = myGroups[i] ;
2163         FAMILY* myFamily = new FAMILY(*mySupport);
2164         myFamily->setIdentifier(i+1);
2165         myFamilies->push_back(myFamily);
2166       }
2167       NumberOfNodesFamilies=myFamilies->size() ;
2168     }
2169     for (int i=0 ; i<NumberOfNodesFamilies; i++) {
2170       //SCRUTE(i);
2171       //SCRUTE(myFamilies[i]->getName());
2172       int FamilyIdentifier = (*myFamilies)[i]->getIdentifier() ;
2173       int TotalNumber = (*myFamilies)[i]->getNumberOfElements(MED_ALL_ELEMENTS) ;
2174       if ((*myFamilies)[i]->isOnAllElements())
2175         for (int j=0; j<TotalNumber; j++)
2176           MEDArrayNodeFamily[j]=FamilyIdentifier;
2177       else {
2178         const int * Number = (*myFamilies)[i]->getNumber(MED_ALL_ELEMENTS) ;
2179         for (int j=0; j<TotalNumber; j++)
2180           MEDArrayNodeFamily[Number[j]-1]=FamilyIdentifier ;
2181       }
2182     }
2183
2184     for(int j=0; j<NumberOfNodes; j++) {
2185       SCRUTE(MEDArrayNodeFamily[j]);
2186     }
2187
2188 //     if ( !_ptrMesh->getIsAGrid() )
2189
2190     err = MEDfamEcr(_medIdt, const_cast <char *> ( _meshName.c_str() ),
2191                     MEDArrayNodeFamily, NumberOfNodes, MED_FR::MED_NOEUD,
2192                     (enum MED_FR::med_geometrie_element) MED_NONE);
2193
2194 //     else
2195 //       err = MEDfamGridEcr(_medIdt,
2196 //                        const_cast <char *> (_ptrMesh->_name.c_str()),
2197 //                        MEDArrayNodeFamily,
2198 //                        NumberOfNodes,
2199 //                        MED_FR::MED_LECTURE_ECRITURE,
2200 //                        MED_FR::MED_NOEUD);
2201
2202     if ( err != MED_VALID) 
2203       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't write node family for the |"<< NumberOfNodes
2204                                    << "| nodes in mesh |" 
2205                                    << _ptrMesh->_name.c_str() << "|" ));
2206     delete[] MEDArrayNodeFamily;
2207     //if (true == ToDestroy)
2208     //  for (int i=0; i<NumberOfNodesFamilies; i++)
2209     //    delete myFamilies[i];
2210   }
2211     
2212   { // CELLS RELATED BLOCK
2213     medEntityMesh entity=MED_EN::MED_CELL;
2214     // SOLUTION TEMPORAIRE CAR _ptrMesh->_MEDArray____Family DOIT ETRE ENLEVER DE LA CLASSE MESH
2215     if  ( ( _ptrMesh->existConnectivity(MED_NODAL,entity) )|( _ptrMesh->existConnectivity(MED_DESCENDING,entity) ) ) { 
2216
2217       int numberOfTypes           = _ptrMesh->getNumberOfTypes (entity) ;
2218       const medGeometryElement  * types = _ptrMesh->getTypes         (entity) ;
2219
2220       // We build the array from the families list objects :
2221       int NumberOfElements = _ptrMesh->getNumberOfElements(entity, MED_ALL_ELEMENTS);
2222       int * MEDArrayFamily = new int[NumberOfElements] ;
2223       // family 0 by default
2224       for (int i=0; i<NumberOfElements; i++)
2225         MEDArrayFamily[i]=0;
2226       //vector<FAMILY*> myFamilies = _ptrMesh->getFamilies(entity);
2227       vector<FAMILY*> * myFamilies = &_ptrMesh->_familyCell ;
2228       int NumberOfFamilies = myFamilies->size() ;
2229       //bool ToDestroy = false;
2230       if (0 == NumberOfFamilies) {
2231         //ToDestroy = true ;
2232         vector<GROUP*> myGroups = _ptrMesh->getGroups(entity);
2233         int NumberOfGroups = myGroups.size() ;
2234         // build families from groups
2235         for (int i=0; i<NumberOfGroups; i++) {
2236           SCRUTE( myGroups[i]->getName() );
2237           SUPPORT * mySupport = myGroups[i] ;
2238           FAMILY* myFamily = new FAMILY(*mySupport);
2239           myFamily->setIdentifier(-i-1);
2240           myFamilies->push_back(myFamily);
2241         }
2242         NumberOfFamilies=myFamilies->size() ;
2243       }
2244       for (int i=0 ; i<NumberOfFamilies; i++) {
2245         int FamilyIdentifier = (*myFamilies)[i]->getIdentifier() ;
2246         int TotalNumber = (*myFamilies)[i]->getNumberOfElements(MED_ALL_ELEMENTS) ;
2247         if ((*myFamilies)[i]->isOnAllElements())
2248           for (int ii=0; ii<TotalNumber; ii++)
2249             MEDArrayFamily[ii]=FamilyIdentifier;
2250         else {
2251           const int * Number = (*myFamilies)[i]->getNumber(MED_ALL_ELEMENTS) ;
2252           for (int ii=0; ii<TotalNumber; ii++)
2253             MEDArrayFamily[Number[ii]-1]=FamilyIdentifier ;
2254         }
2255       }
2256
2257       const int * typeCount = _ptrMesh->getGlobalNumberingIndex(entity) ;
2258
2259       for (int i=0; i<numberOfTypes; i++) {
2260
2261         err = MEDfamEcr(_medIdt, const_cast <char *> ( _meshName.c_str() ),
2262                         (MEDArrayFamily+typeCount[i]-1),
2263                         (typeCount[i+1]-typeCount[i]),
2264                         (MED_FR::med_entite_maillage) entity,
2265                         (MED_FR::med_geometrie_element) types[i]); 
2266
2267         MESSAGE("OK "<<i);
2268         if ( err != MED_VALID) 
2269           throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't write family for the |"<< _ptrMesh->getNumberOfElements(entity, types[i])
2270                                        << "| cells of geometric type |" << MED_FR::geoNames[ (MED_FR::med_geometrie_element) types[i]] <<"|in mesh |"      
2271                                        << _ptrMesh->_name.c_str() << "|" ));   
2272       }
2273       delete[] MEDArrayFamily ;
2274       //if (true == ToDestroy) {
2275       //  int NumberOfFamilies = myFamilies->size();
2276       //  for (int i=0; i<NumberOfFamilies; i++)
2277       //    delete myFamilies[i];
2278       //}
2279     }
2280   }
2281
2282   { // FACE RELATED BLOCK
2283     medEntityMesh entity=MED_EN::MED_FACE;
2284     // SOLUTION TEMPORAIRE CAR _ptrMesh->_MEDArray____Family DOIT ETRE ENLEVER DE LA CLASSE MESH
2285     if  ( ( _ptrMesh->existConnectivity(MED_NODAL,entity) )|( _ptrMesh->existConnectivity(MED_DESCENDING,entity) ) ) { 
2286
2287       int numberOfTypes           = _ptrMesh->getNumberOfTypes (entity) ;
2288       const medGeometryElement  * types = _ptrMesh->getTypes         (entity) ;
2289       SCRUTE(numberOfTypes);
2290       
2291       int numberOfElements = _ptrMesh->getNumberOfElements(entity, MED_ALL_ELEMENTS) ;
2292       int * familyArray = new int[numberOfElements] ;
2293       for (int i=0;i<numberOfElements;i++)
2294         familyArray[i]=0;
2295
2296       int numberOfFamilies = _ptrMesh->getNumberOfFamilies(entity) ;
2297       //vector<FAMILY*> myFamilies = _ptrMesh->getFamilies(entity) ;
2298       vector<FAMILY*> * myFamilies = &_ptrMesh->_familyFace ;
2299       //bool ToDestroy = false;
2300       if (0 == numberOfFamilies) {
2301         //ToDestroy = true ;
2302         vector<GROUP*> myGroups = _ptrMesh->getGroups(entity);
2303         int NumberOfGroups = myGroups.size() ;
2304         // build families from groups
2305         for (int i=0; i<NumberOfGroups; i++) {
2306           SCRUTE( myGroups[i]->getName() );
2307           SUPPORT * mySupport = myGroups[i] ;
2308           FAMILY* myFamily = new FAMILY(*mySupport);
2309           myFamily->setIdentifier(-i-1000);
2310           myFamilies->push_back(myFamily);
2311         }
2312         numberOfFamilies=myFamilies->size() ;
2313       }
2314       for (int i=0;i<numberOfFamilies;i++) {
2315         int familyNumber = (*myFamilies)[i]->getIdentifier() ;
2316         int numberOfFamilyElements = (*myFamilies)[i]->getNumberOfElements(MED_ALL_ELEMENTS) ;
2317         if ((*myFamilies)[i]->isOnAllElements())
2318           for (int ii=0; ii<numberOfFamilyElements; ii++)
2319             familyArray[ii]=familyNumber;
2320         else {
2321           const int * myFamilyElements = (*myFamilies)[i]->getNumber(MED_ALL_ELEMENTS) ;
2322           for (int ii=0;ii<numberOfFamilyElements;ii++)
2323             familyArray[myFamilyElements[ii]-1]=familyNumber;
2324         }
2325       }
2326
2327       const int * typeCount = _ptrMesh->getGlobalNumberingIndex(entity) ;
2328
2329       for (int i=0; i<numberOfTypes; i++) {
2330         int typeNumberOfElements = typeCount[i+1] - typeCount[i] ;
2331
2332         err = MEDfamEcr(_medIdt, const_cast <char *> ( _meshName.c_str() ),
2333                         familyArray+typeCount[i]-1, typeNumberOfElements,
2334                         (MED_FR::med_entite_maillage) entity,
2335                         (MED_FR::med_geometrie_element) types[i]); 
2336
2337         if ( err != MED_VALID) 
2338           throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't write family for the |"<< _ptrMesh->getNumberOfElements(entity, types[i])
2339                                        << "| faces of geometric type |" << MED_FR::geoNames[ (MED_FR::med_geometrie_element) types[i]] <<"|in mesh |"      
2340                                        << _ptrMesh->_name.c_str() << "|" ));   
2341       }
2342       delete[] familyArray ;
2343       //if (true == ToDestroy) {
2344       //  int NumberOfFamilies = myFamilies->size();
2345       //    for (int i=0; i<NumberOfFamilies; i++)
2346       //      delete myFamilies[i];
2347       //}
2348     }
2349   }
2350
2351   { // EDGE RELATED BLOCK
2352     //medEntityMesh entity=MED_EN::MED_FACE;
2353     medEntityMesh entity=MED_EN::MED_EDGE;
2354     // SOLUTION TEMPORAIRE CAR _ptrMesh->_MEDArray____Family DOIT ETRE ENLEVER DE LA CLASSE MESH
2355     if  ( ( _ptrMesh->existConnectivity(MED_NODAL,entity) )|( _ptrMesh->existConnectivity(MED_DESCENDING,entity) ) ) { 
2356
2357       int numberOfTypes           = _ptrMesh->getNumberOfTypes (entity) ;
2358       const medGeometryElement  * types = _ptrMesh->getTypes         (entity) ;
2359       
2360       int numberOfElements = _ptrMesh->getNumberOfElements(entity, MED_ALL_ELEMENTS) ;
2361       int * familyArray = new int[numberOfElements] ;
2362       for (int i=0;i<numberOfElements;i++)
2363         familyArray[i]=0;
2364
2365       int numberOfFamilies = _ptrMesh->getNumberOfFamilies(entity) ;
2366       //vector<FAMILY*> myFamilies = _ptrMesh->getFamilies(entity) ;
2367       vector<FAMILY*> * myFamilies = &_ptrMesh->_familyEdge ;
2368       //bool ToDestroy = false;
2369       if (0 == numberOfFamilies) {
2370         //ToDestroy = true ;
2371         vector<GROUP*> myGroups = _ptrMesh->getGroups(entity);
2372         int NumberOfGroups = myGroups.size() ;
2373         // build families from groups
2374         for (int i=0; i<NumberOfGroups; i++) {
2375           SCRUTE( myGroups[i]->getName() );
2376           SUPPORT * mySupport = myGroups[i] ;
2377           FAMILY* myFamily = new FAMILY(*mySupport);
2378           myFamily->setIdentifier(-i-2000);
2379           myFamilies->push_back(myFamily);
2380         }
2381         numberOfFamilies=myFamilies->size() ;
2382       }
2383       for (int i=0;i<numberOfFamilies;i++) {
2384         int familyNumber = (*myFamilies)[i]->getIdentifier() ;
2385         int numberOfFamilyElements = (*myFamilies)[i]->getNumberOfElements(MED_ALL_ELEMENTS) ;
2386         if ((*myFamilies)[i]->isOnAllElements())
2387           for (int ii=0; ii<numberOfFamilyElements; ii++)
2388             familyArray[ii]=familyNumber;
2389         else {
2390           const int * myFamilyElements = (*myFamilies)[i]->getNumber(MED_ALL_ELEMENTS) ;
2391           for (int ii=0;ii<numberOfFamilyElements;ii++)
2392             familyArray[myFamilyElements[ii]-1]=familyNumber;
2393         }
2394       }
2395
2396       const int * typeCount = _ptrMesh->getGlobalNumberingIndex(entity) ;
2397
2398       for (int i=0; i<numberOfTypes; i++) {
2399         int typeNumberOfElements = typeCount[i+1] - typeCount[i] ;
2400
2401         err = MEDfamEcr(_medIdt, const_cast <char *> ( _meshName.c_str() ),
2402                         familyArray+typeCount[i]-1, typeNumberOfElements,
2403                         (MED_FR::med_entite_maillage) entity,
2404                         (MED_FR::med_geometrie_element) types[i]); 
2405
2406         if ( err != MED_VALID) 
2407           throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't write family for the |"<< _ptrMesh->getNumberOfElements(entity, types[i])
2408                                        << "| edges of geometric type |" << MED_FR::geoNames[ (MED_FR::med_geometrie_element) types[i]] <<"|in mesh |"      
2409                                        << _ptrMesh->_name.c_str() << "|" ));   
2410       }
2411       delete[] familyArray ;
2412       //if (true == ToDestroy) {
2413       //  int NumberOfFamilies = myFamilies->size();
2414       //  for (int i=0; i<NumberOfFamilies; i++)
2415       //    delete myFamilies[i];
2416       //}
2417     }
2418   }
2419     
2420   END_OF(LOC);
2421   return MED_VALID;
2422 }
2423
2424 int MED_MESH_WRONLY_DRIVER::writeFamilies(vector<FAMILY*> & families ) const {
2425   
2426   const char * LOC="int MED_MESH_WRONLY_DRIVER::writeFamilies(vector<FAMILY*> families) const : ";
2427   BEGIN_OF(LOC);
2428
2429   MED_FR::med_err err;
2430   
2431   MESSAGE(LOC<<" families.size() :"<<families.size());
2432
2433   for (unsigned int i=0; i< families.size(); i++) {
2434
2435     int      numberOfAttributes         = families[i]->getNumberOfAttributes ();
2436     string   attributesDescriptions     = "";
2437
2438     // Recompose the attributes descriptions arg for MED
2439     for (int j=0; j < numberOfAttributes; j++) {
2440         
2441       string attributeDescription = families[i]->getAttributeDescription(j+1);
2442         
2443       if ( attributeDescription.size() > MED_TAILLE_DESC )
2444         throw MEDEXCEPTION( LOCALIZED(STRING(LOC) << "The size of the attribute description n° |" << j+1 << "| of the family |" << families[i]->getName()
2445                                       << "| with identifier |" << families[i]->getIdentifier()  << "| is |" 
2446                                       <<  attributeDescription.size()  <<"| and is more than |" <<  MED_TAILLE_DESC << "|")) ;
2447         
2448       attributesDescriptions += attributeDescription;
2449     }
2450       
2451
2452     int      numberOfGroups  = families[i]->getNumberOfGroups();
2453     string   groupsNames(numberOfGroups*MED_TAILLE_LNOM,'\0') ;
2454     // Recompose the groups names arg for MED
2455     for (int j=0; j < numberOfGroups; j++) {
2456
2457       string groupName = families[i]->getGroupName(j+1);
2458        
2459       if ( groupName.size() > MED_TAILLE_LNOM )
2460         throw MEDEXCEPTION( LOCALIZED(STRING(LOC) << "The size of the group name  n° |" << j+1 << "| of the family |" << families[i]->getName()
2461                                       << "| with identifier |" << families[i]->getIdentifier()  << "| is |" 
2462                                       <<  groupName.size()  <<"| and is more than |" << MED_TAILLE_LNOM << "|")) ;
2463         
2464
2465       int length = min(MED_TAILLE_LNOM,(int)groupName.size());
2466       groupsNames.replace(j*MED_TAILLE_LNOM,length, groupName,0,length);
2467       
2468     }
2469
2470     // test if the family already exists (HDF trick waiting a MED evolution to be replaced)
2471     string dataGroupFam = "/ENS_MAA/"+_meshName+"/FAS/"+families[i]->getName()+"/";  
2472     SCRUTE("|"<<dataGroupFam<<"|");
2473     err =_MEDdatagroupOuvrir(_medIdt,const_cast <char *> (dataGroupFam.c_str()) ) ;
2474     if ( err < MED_VALID ) {
2475       SCRUTE(err);
2476
2477       MESSAGE(LOC<<"families[i]->getName().c_str() : "<<families[i]->getName().c_str());
2478       MESSAGE(LOC<<"_meshName.c_str() : "<<_meshName.c_str());
2479       MESSAGE(LOC<<"families[i]->getIdentifier() : "<<families[i]->getIdentifier());
2480       MESSAGE(LOC<<"numberOfAttributes : "<<numberOfAttributes);
2481         
2482       //MESSAGE(LOC<<"families[i]->getAttributesIdentifiers() : "<<families[i]->getAttributesIdentifiers()[0]);
2483       //MESSAGE(LOC<<"families[i]->getAttributesValues() : "<<families[i]->getAttributesValues()[0]);
2484       MESSAGE(LOC<<"attributesDescriptions.c_str() : "<<attributesDescriptions.c_str());
2485       MESSAGE(LOC<<"numberOfGroups : "<<numberOfGroups);
2486       MESSAGE(LOC<<"groupsNames.c_str() : "<<groupsNames.c_str());
2487
2488       err = MED_FR::MEDfamCr( _medIdt, 
2489                               const_cast <char *> ( _meshName.c_str() ),
2490                               const_cast <char *> ( families[i]->getName().c_str() ),
2491                               families[i]->getIdentifier(), 
2492                               families[i]->getAttributesIdentifiers(),
2493                               families[i]->getAttributesValues(),
2494                               const_cast <char *> (attributesDescriptions.c_str()), 
2495                               numberOfAttributes,  
2496                               const_cast <char *> (groupsNames.c_str()), 
2497                               numberOfGroups);
2498       SCRUTE(err);
2499       if ( err != MED_VALID) 
2500         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't create family |" << families[i]->getName()
2501                                      << "| with identifier |" << families[i]->getIdentifier()  << "| groups names |" 
2502                                      << groupsNames  <<"| and  attributes descriptions |" << attributesDescriptions << "|")) ;
2503     }
2504     else
2505       _MEDdatagroupFermer(_medIdt);
2506
2507
2508   }
2509
2510   END_OF(LOC);
2511     
2512   return MED_VALID;
2513 }
2514
2515
2516 // A FAIRE POUR LES NOEUDS ET LES ELEMENTS ret = MEDfamEcr(
2517
2518
2519
2520 /*--------------------- RDWR PART -------------------------------*/
2521
2522 MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER():MED_MESH_DRIVER()
2523 {
2524 }
2525
2526 MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER(const string & fileName,
2527                                            MESH * ptrMesh):
2528   MED_MESH_DRIVER(fileName,ptrMesh,MED_RDWR)
2529 {
2530   MESSAGE("MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
2531 }
2532
2533 MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER(const MED_MESH_RDWR_DRIVER & driver): 
2534   MED_MESH_RDONLY_DRIVER::MED_MESH_DRIVER(driver)
2535 {
2536 }
2537
2538 MED_MESH_RDWR_DRIVER::~MED_MESH_RDWR_DRIVER() {
2539   //MESSAGE("MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed");
2540
2541   
2542 GENDRIVER * MED_MESH_RDWR_DRIVER::copy(void) const
2543 {
2544   return new MED_MESH_RDWR_DRIVER(*this);
2545 }
2546
2547 void MED_MESH_RDWR_DRIVER::write(void) const
2548   throw (MEDEXCEPTION)
2549 {
2550   MED_MESH_WRONLY_DRIVER::write();
2551 }
2552 void MED_MESH_RDWR_DRIVER::read (void)
2553   throw (MEDEXCEPTION)
2554 {
2555   MED_MESH_RDONLY_DRIVER::read();
2556 }
2557