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