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