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