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