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