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