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