Salome HOME
Fix problem of make distcheck
[modules/med.git] / src / MEDMEM / MEDMEM_MedMeshDriver.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "MEDMEM_MedMeshDriver.hxx"
24 #include "MEDMEM_GenDriver.hxx"
25 #include "MEDMEM_DriversDef.hxx"
26
27 #include "MEDMEM_Family.hxx"
28 #include "MEDMEM_Group.hxx"
29 #include "MEDMEM_Coordinate.hxx"
30 #include "MEDMEM_Connectivity.hxx"
31 #include "MEDMEM_Mesh.hxx"
32 #include "MEDMEM_CellModel.hxx"
33 #include "MEDMEM_Grid.hxx"
34 #include "MEDMEM_MedVersion.hxx"
35
36 using namespace std;
37 using namespace MED_EN;
38 using namespace MEDMEM;
39
40 namespace med_2_3 {
41   extern "C" {
42     extern med_idt _MEDdatagroupOuvrir(med_idt pid, char *nom);
43     extern med_err _MEDdatagroupFermer(med_idt id);
44   }
45 }
46
47 // Every memory allocation made in the MedDriver members function are desallocated in the Mesh destructor
48
49 MED_MESH_DRIVER::MED_MESH_DRIVER():
50   GENDRIVER(MED_DRIVER),
51   _ptrMesh(( GMESH *)MED_NULL),
52   _meshName(""),
53   _medIdt(MED_INVALID)
54 {
55 }
56
57 MED_MESH_DRIVER::MED_MESH_DRIVER(const std::string &    fileName,
58                                  GMESH *                ptrMesh,
59                                  MED_EN::med_mode_acces accessMode): 
60   GENDRIVER(fileName, accessMode, MED_DRIVER),
61   _ptrMesh(ptrMesh), 
62   _meshName(""),
63   _medIdt(MED_INVALID)
64 {
65 }
66
67 MED_MESH_DRIVER::MED_MESH_DRIVER(const MED_MESH_DRIVER & driver): 
68   GENDRIVER(driver),
69   _ptrMesh(driver._ptrMesh),
70   _meshName(driver._meshName),
71   _medIdt(driver._medIdt)
72 {
73
74 }
75
76 MED_MESH_DRIVER::~MED_MESH_DRIVER()
77 {
78   MESSAGE_MED("MED_MESH_DRIVER::~MED_MESH_DRIVER()has been destroyed");
79 }
80
81 void MED_MESH_DRIVER::setMeshName(const string & meshName) 
82
83   _meshName = meshName; 
84 }
85
86 string  MED_MESH_DRIVER::getMeshName() const 
87
88   return _meshName; 
89 }
90
91 void MED_MESH_DRIVER::open()
92 {
93 const char * LOC = "MED_MESH_DRIVER::open()";
94   BEGIN_OF_MED(LOC);
95
96   int accessMode = getMedAccessMode( _accessMode );
97   MESSAGE_MED(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< accessMode);
98   _medIdt = med_2_3::MEDfileOpen(_fileName.c_str(),(med_2_3::med_access_mode) accessMode);
99   MESSAGE_MED(LOC<<" _medIdt : "<< _medIdt );
100   if (_medIdt > 0)
101     _status = MED_OPENED;
102   else {
103     _medIdt = MED_INVALID;
104     _status = MED_CLOSED;
105     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Could not open file "<<_fileName<<" in mode "<<_accessMode));
106   }
107
108   END_OF_MED(LOC);
109 }
110
111 void MED_MESH_DRIVER::close()
112 {
113   const char * LOC = "MED_MESH_DRIVER::close() ";
114   BEGIN_OF_MED(LOC);
115   int err = 0;
116   if ( _status == MED_OPENED) {
117
118     err = med_2_3::MEDfileClose(_medIdt);
119     // san -- MED5873 : Calling H5close() here leads to failure of SALOMEDS::StudyManager_i::_SaveAs()
120     // method during study saving process. MEDfermer() seems sufficient for closing a file.
121     //H5close(); // If we call H5close() all the files are closed.
122     if (err)
123       throw MEDEXCEPTION( LOCALIZED(STRING(LOC)<<" Error when closing file ! " << err));
124
125     MESSAGE_MED(LOC <<": _medIdt= " << _medIdt );
126     MESSAGE_MED(LOC<<": MEDfermer : err    = " << err );
127     _status = MED_CLOSED;
128     _medIdt = MED_INVALID;
129   }
130   END_OF_MED(LOC);
131 }
132
133 //A FAIRE UTILISER LES MAPS...
134 const med_2_3::med_geometry_type  MED_MESH_DRIVER::all_cell_type[MED_N_CELL_GEO_FIXED_CON]=
135   { MED_POINT1,MED_SEG2,MED_SEG3,MED_SEG4,MED_TRIA3,MED_QUAD4,MED_TRIA6,MED_TRIA7,MED_QUAD8,MED_QUAD9,
136     MED_TETRA4,MED_PYRA5,MED_PENTA6,MED_HEXA8,MED_TETRA10,MED_OCTA12,MED_PYRA13,
137     MED_PENTA15, MED_HEXA20,MED_HEXA27};
138
139 const char * const MED_MESH_DRIVER::all_cell_type_tab [MED_N_CELL_GEO_FIXED_CON]=
140   { "MED_POINT1","MED_SEG2","MED_SEG3","MEDMEM_SEG4","MED_TRIA3","MED_QUAD4","MED_TRIA6","MEDMEM_TRIA7","MED_QUAD8","MEDMEM_QUAD9",
141     "MED_TETRA4","MED_PYRA5","MED_PENTA6","MED_HEXA8","MED_TETRA10","MEDMEM_OCTA12","MED_PYRA13",
142     "MED_PENTA15","MED_HEXA20","MEDMEM_HEXA27"};
143
144
145 //---------------------------------- RDONLY PART -------------------------------------------------------------
146
147 MED_MESH_RDONLY_DRIVER::MED_MESH_RDONLY_DRIVER():MED_MESH_DRIVER(),_computeFaces(true)
148 {
149   this->GENDRIVER::_accessMode = MED_EN::RDONLY;
150 }
151
152 MED_MESH_RDONLY_DRIVER::MED_MESH_RDONLY_DRIVER(const string & fileName,
153                                                GMESH *        ptrMesh):
154   MED_MESH_DRIVER(fileName,ptrMesh,RDONLY),
155   _computeFaces(true)
156 {
157   MESSAGE_MED("MED_MESH_RDONLY_DRIVER::MED_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
158 }
159
160 MED_MESH_RDONLY_DRIVER::MED_MESH_RDONLY_DRIVER(const MED_MESH_RDONLY_DRIVER & driver):
161   MED_MESH_DRIVER(driver),
162   _computeFaces(driver._computeFaces)
163 {
164 }
165
166 MED_MESH_RDONLY_DRIVER::~MED_MESH_RDONLY_DRIVER()
167 {
168   //MESSAGE_MED("MED_MESH_RDONLY_DRIVER::~MED_MESH_RDONLY_DRIVER() has been destroyed");
169 }
170
171 GENDRIVER * MED_MESH_RDONLY_DRIVER::copy(void) const
172 {
173   return new MED_MESH_RDONLY_DRIVER(*this);
174 }
175
176 void MED_MESH_RDONLY_DRIVER::merge ( const GENDRIVER& driver )
177 {
178   MED_MESH_DRIVER::merge( driver );
179
180   const MED_MESH_RDONLY_DRIVER* other =
181     dynamic_cast< const MED_MESH_RDONLY_DRIVER* >( &driver );
182   if ( other ) {
183     _computeFaces = other->_computeFaces;
184   }
185 }
186
187 void MED_MESH_RDONLY_DRIVER::write( void ) const
188 {
189   throw MEDEXCEPTION("MED_MESH_RDONLY_DRIVER::write : Can't write with a RDONLY driver !");
190 }
191
192 void MED_MESH_RDONLY_DRIVER::read(void)
193 {
194   const char * LOC = "MED_MESH_RDONLY_DRIVER::read() : ";
195   BEGIN_OF_MED(LOC);
196   if (_status != MED_OPENED)
197     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The _idt of file " << _fileName
198                                  << " is : " << _medIdt << " (the file is not opened)."));
199
200   if ( ( _meshName.empty() ) && ( _ptrMesh->_name.empty() ) )
201     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)
202                                  <<" neither <meshName> is set in driver nor in object MESH."));
203
204   // If _meshName is not set in driver, try to use _ptrMesh->_name
205   if ( ( _meshName.empty() ) && ( !_ptrMesh->_name.empty() ) )
206     _meshName = _ptrMesh->_name;
207
208   if ( _meshName.size() > MED_NAME_SIZE )
209     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)
210                                  <<" <meshName> size in object driver MESH is > MED_TAILLE_NOM ."));
211
212   _ptrMesh->_name = _meshName;
213
214   // 0020058: Check version of med, which was used to save the file.
215   // 0020058: An assertion happens in MEDcoordLire(), if this version
216   // 0020058: is higher than the currently used version of med product.
217   med_2_3::med_int aMajor, aMinor, aRelease;
218   med_2_3::med_int aMajorCurr=3, aMinorCurr=1, aReleaseCurr=0;
219
220   med_err aRet = med_2_3::MEDfileNumVersionRd(_medIdt, &aMajor, &aMinor, &aRelease);
221
222   int aVersionHex     = (aMajor << 16 | aMinor << 8 | aRelease);
223   int aVersionHexCurr = (aMajorCurr << 16 | aMinorCurr << 8 | aReleaseCurr);
224
225   if (aRet != 0 || aVersionHex > aVersionHexCurr) {
226     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " cannot read file " << _fileName
227                                  << " of version (" << aMajor << "." << aMinor << "." << aRelease
228                                  << ") higher than the currently used version of med ("
229                                  << aMajorCurr << "." << aMinorCurr << "." << aReleaseCurr << ")."));
230   }
231   // 0020058: end of version check
232
233   SCRUTE_MED(_ptrMesh->getIsAGrid());
234
235   int numberOfMeshes = med_2_3::MEDnMesh(_medIdt);
236   if ( numberOfMeshes < 1 )
237     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " no meshes at all in file " << _fileName));
238
239   // check mesh nature, unstructured or not (PAL14113)
240   // and set space dimension
241   {
242     int naxis=med_2_3::MEDmeshnAxisByName(_medIdt,_meshName.c_str());
243     if ( naxis < 0 )
244       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " no mesh |" << _meshName
245                                    << "| in file " << _fileName));
246     if ( naxis == 0 )
247       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Mesh |" << _meshName
248                                    << "| has invalid space dimension 0."));
249
250     med_2_3::med_int spaceDimension,meshDimension;
251     med_2_3::med_mesh_type meshType;
252     char commentp3[MED_COMMENT_SIZE+1];
253     char dtunittp3[MED_LNAME_SIZE+1];
254     med_2_3::med_sorting_type sttp3;
255     int nstep;
256     med_2_3::med_axis_type axtypp3;
257     naxis = std::max(3, naxis); // safe enough?
258     char *t1pp3=new char[naxis*MED_SNAME_SIZE+1];
259     char *t2pp3=new char[naxis*MED_SNAME_SIZE+1];
260     med_2_3::MEDmeshInfoByName(_medIdt,_meshName.c_str(),&spaceDimension,&meshDimension,&meshType,commentp3,dtunittp3,&sttp3,&nstep,&axtypp3,t1pp3,t2pp3);
261     delete [] t1pp3;
262     delete [] t2pp3;
263
264     if ((meshType == med_2_3::MED_STRUCTURED_MESH ) != _ptrMesh->getIsAGrid())
265       {
266         if ( _ptrMesh->getIsAGrid() )
267           throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Mesh type mismatch. "
268                                        "Class MESH must be used for an unstructured mesh"));
269         else
270           throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Mesh type mismatch. "
271                                        "Class GRID must be used for a structured mesh"));
272       }
273     if ( meshDimension > spaceDimension )
274       spaceDimension = meshDimension;
275
276     if ( spaceDimension < 1 )
277       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The space dimension |" << spaceDimension
278                                    << "| seems to be incorrect for the mesh : |" << _meshName << "|"));
279     _ptrMesh->_spaceDimension = spaceDimension;
280     
281   }
282
283   if (_ptrMesh->getIsAGrid())
284   {
285     getGRID();
286     {
287       if (getFAMILY() != MED_VALID)
288         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getFAMILY when the mesh is a grid"));
289       buildAllGroups(_ptrMesh->_groupNode, _ptrMesh->_familyNode);
290     }
291     END_OF_MED(LOC);
292     return;
293   }
294
295   if (getCOORDINATE() != MED_VALID)
296     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getCOORDINATE"  ));
297
298   if (getCONNECTIVITY() != MED_VALID)
299     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getCOONECTIVITY"));
300
301   if (getFAMILY() != MED_VALID)
302     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getFAMILY"      ));
303
304   if (_computeFaces)
305     updateFamily();
306
307   // we build all groups
308   // on node
309   buildAllGroups(_ptrMesh->_groupNode,_ptrMesh->_familyNode);
310   // on cell
311   buildAllGroups(_ptrMesh->_groupCell,_ptrMesh->_familyCell);
312
313   if (_ptrMesh->getMeshDimension() == 3)
314     // on face
315     buildAllGroups(_ptrMesh->_groupFace,_ptrMesh->_familyFace);
316 //   else if (_ptrMesh->getMeshDimension() == 2) -- PAL13414
317   if (_ptrMesh->getMeshDimension() > 1)
318     // on edge
319     buildAllGroups(_ptrMesh->_groupEdge,_ptrMesh->_familyEdge);
320
321   _ptrMesh->_name = healName( _ptrMesh->_name );
322
323   END_OF_MED(LOC);
324 }
325
326 //=======================================================================
327 //function : getGRID
328 //purpose  :
329 //=======================================================================
330
331 void MED_MESH_RDONLY_DRIVER::getGRID()
332 {
333   const char * LOC = "MED_MESH_RDONLY_DRIVER::getGRID() : ";
334   BEGIN_OF_MED(LOC);
335
336   if (_status!=MED_OPENED)
337     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "med file is not opened"));
338
339   GRID * ptrGrid = (GRID *) _ptrMesh;
340
341   SCRUTE_MED(ptrGrid);
342
343   int err, i;
344
345   int numberOfMeshesInFile = med_2_3::MEDnMesh(_medIdt);
346
347   if (numberOfMeshesInFile == MED_INVALID)
348     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Problem in File where the mesh " << _meshName << " is supposed to be stored"));
349   int MeshDimension;
350   int SpaceDimensionRead;
351   string tmp_nom_coord (MED_SNAME_SIZE*(_ptrMesh->_spaceDimension)+1,' ');
352   string tmp_unit_coord(MED_SNAME_SIZE*(_ptrMesh->_spaceDimension)+1,' ');
353   char * tmp_nom = (const_cast <char *> ( tmp_nom_coord.c_str())  );
354   char * tmp_unit= (const_cast <char *> ( tmp_unit_coord.c_str()) );
355   med_2_3::med_axis_type rep;
356   med_2_3::med_int dtp3,itp3;
357   med_2_3::med_float ttpp3;
358   for (int index = 0; index < numberOfMeshesInFile; index++)
359     {
360       char meshName[MED_NAME_SIZE+1]="";
361       char meshDescription[MED_COMMENT_SIZE+1]="";
362       med_2_3::med_int meshDim;
363       med_2_3::med_mesh_type meshType;
364       med_2_3::med_int spaceDimp3;
365       char dtunittp3[MED_LNAME_SIZE+1];
366       med_2_3::med_sorting_type stypp3;
367       med_2_3::med_int nstepp3;
368       int naxis=med_2_3::MEDmeshnAxis(_medIdt,(index+1));
369       char *axisnamep3=new char[naxis*MED_SNAME_SIZE+1];
370       char *axisunitp3=new char[naxis*MED_SNAME_SIZE+1];
371       med_2_3::med_axis_type axtpp3;
372       err = med_2_3::MEDmeshInfo(_medIdt,(index+1),meshName, &spaceDimp3, &meshDim,&meshType, meshDescription, dtunittp3,&stypp3,&nstepp3,&axtpp3,axisnamep3,axisunitp3);
373       MESSAGE_MED(LOC<<": Mesh n°"<< (index+1) <<" nammed "<< meshName << " with the description " << meshDescription << " is structured");
374       if (_meshName == string(meshName))
375         {
376           _ptrMesh->_description = meshDescription;
377           _ptrMesh->_name = meshName;
378           MeshDimension=meshDim;
379           SpaceDimensionRead=spaceDimp3;
380           rep=axtpp3;
381           strncpy(tmp_nom,axisnamep3,naxis*_ptrMesh->_spaceDimension+1);
382           strncpy(tmp_unit,axisunitp3,naxis*_ptrMesh->_spaceDimension+1);
383           med_2_3::MEDmeshComputationStepInfo(_medIdt,meshName,1,&dtp3,&itp3,&ttpp3);
384         }
385       delete [] axisnamep3;
386       delete [] axisunitp3;
387     }
388
389   MED_EN::med_grid_type gridType = ptrGrid->getGridType();
390   if ( ptrGrid->_is_default_gridType )
391   {
392     med_2_3::med_grid_type type;
393     MEDmeshGridTypeRd(_medIdt,_ptrMesh->_name.c_str(),&type);
394     gridType = ptrGrid->_gridType = (MED_EN::med_grid_type) type;
395     ptrGrid->_is_default_gridType = false;
396   }
397
398   MESSAGE_MED(LOC<<": Mesh processed is nammed "<< _ptrMesh->_name << " with the description " << _ptrMesh->_description << " is structured with the type " << gridType);
399
400
401   if (MeshDimension == MED_INVALID)
402     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The mesh dimension |" <<
403                                  MeshDimension << "| seems to be incorrect " <<
404                                  "for the mesh : |" << _meshName << "|"));
405
406   // Read or get the dimension of the space for the mesh <_meshName>
407   int SpaceDimension = MeshDimension;
408
409   if (SpaceDimensionRead != MED_INVALID) SpaceDimension = SpaceDimensionRead;
410
411   _ptrMesh->_spaceDimension = SpaceDimension;
412
413
414   // Read Array length
415   int * ArrayLen[] = { & ptrGrid->_iArrayLength,
416                        & ptrGrid->_jArrayLength,
417                        & ptrGrid->_kArrayLength  };
418
419   MESSAGE_MED(LOC << "The mesh is a " << _ptrMesh->getMeshDimension() << "D mesh on a " << _ptrMesh->_spaceDimension << "D space");
420
421   int NumberOfNodes;
422
423   //  if (gridType == MED_EN::MED_GRILLE_STANDARD)
424   if (gridType == MED_EN::MED_BODY_FITTED)
425     {
426       med_2_3::med_int * structure = new med_2_3::med_int[MeshDimension];
427
428       err = med_2_3::MEDmeshGridStructRd(_medIdt,_ptrMesh->_name.c_str(),dtp3,itp3,structure);
429
430       if (err != MED_VALID)
431         throw MEDEXCEPTION(STRING(LOC) <<"Error in reading the structure of grid : |" << _meshName << "|" );
432
433       NumberOfNodes = 1;
434
435       for (int idim = 0; idim < MeshDimension; idim++)
436         {
437           MESSAGE_MED(LOC<<"structure dim " << idim << " " << structure[idim]);
438
439           ArrayLen [idim][0] = structure[idim];
440           NumberOfNodes = NumberOfNodes*structure[idim];
441         }
442
443       delete [] structure;
444
445       if ( NumberOfNodes == MED_INVALID )
446         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"The number of nodes |" <<
447                                      NumberOfNodes <<
448                                      "| seems to be incorrect "
449                                      << "for the mesh : |" <<
450                                      _meshName << "|" ));
451
452       // create coordinates and its structure
453       ptrGrid->_coordinate = new COORDINATE(SpaceDimension,NumberOfNodes,
454                                             MED_EN::MED_FULL_INTERLACE);
455
456       err = med_2_3::MEDmeshNodeCoordinateRd(_medIdt,_ptrMesh->_name.c_str(),dtp3,itp3,med_2_3::MED_FULL_INTERLACE,const_cast<double *>(ptrGrid->_coordinate->_coordinate.get(MED_EN::MED_FULL_INTERLACE)));
457
458       if (err != MED_VALID)
459         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't read coordinates of the |" <<
460                                      NumberOfNodes << "| nodes for the mesh : |" <<
461                                      _meshName << "| of space dimension |" <<
462                                      SpaceDimension << "| with units names |" <<
463                                      tmp_nom << "| and units |" <<
464                                      tmp_unit << " |"));
465
466     }
467   else if ((gridType == MED_EN::MED_CARTESIAN) ||
468            (gridType == MED_EN::MED_POLAR))
469     {
470       NumberOfNodes = 1;
471
472       double * Array[] = { (double*) 0, (double*) 0, (double*) 0 };
473
474       for (int idim = 0; idim < _ptrMesh->getMeshDimension(); ++idim)
475         {
476           med_2_3::med_data_type table;
477           if (idim == 0) table = med_2_3::MED_COORDINATE_AXIS1;
478           else if (idim == 1) table = med_2_3::MED_COORDINATE_AXIS2;
479           else if (idim == 2) table = med_2_3::MED_COORDINATE_AXIS3;
480           
481           med_2_3::med_bool chgtpp3,trsfpp3;
482           int length = med_2_3::MEDmeshnEntity(_medIdt,_ptrMesh->_name.c_str(),dtp3,itp3,med_2_3::MED_NODE,MED_NONE,table,med_2_3::MED_NO_CMODE,&chgtpp3,&trsfpp3);
483
484           if ( length <= MED_VALID )
485             throw MEDEXCEPTION(STRING(LOC) <<"The number of nodes |" << length <<
486                                "| seems to be incorrect "
487                                << "for the mesh : |" << _meshName << "|" );
488
489           ArrayLen [idim][0] = length;
490           NumberOfNodes *= length;
491
492           Array [idim] = new double [ length ];
493
494           err = med_2_3::MEDmeshGridIndexCoordinateRd(_medIdt,_ptrMesh->_name.c_str(),dtp3,itp3,idim+1,Array [idim]);
495
496           if (err != MED_VALID)
497             throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Error in reading coordinates indices " <<
498                                          idim << "of the grid : |" <<
499                                          _meshName << "|" ));
500         }
501
502       ptrGrid->_iArray = Array[0];
503       ptrGrid->_jArray = Array[1];
504       ptrGrid->_kArray = Array[2];
505
506       // create coordinates
507       ptrGrid->_coordinate = new COORDINATE(SpaceDimension,NumberOfNodes,
508                                             MED_EN::MED_FULL_INTERLACE);
509
510       if (gridType == MED_EN::MED_CARTESIAN)
511         rep = med_2_3::MED_CARTESIAN;
512       else if (gridType == MED_EN::MED_POLAR)
513         {
514           if (SpaceDimension == 2) rep = med_2_3::MED_CYLINDRICAL;
515           else if (SpaceDimension == 3) rep = med_2_3::MED_SPHERICAL;
516         }
517     }
518   else
519     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<" bad grid type : " << gridType));
520
521   // set coordinate names
522
523   for (i=0; i<_ptrMesh->_spaceDimension; ++i )
524   {
525     string myStringName(tmp_nom_coord,i*MED_SNAME_SIZE,MED_SNAME_SIZE);
526     string myStringUnit(tmp_unit_coord,i*MED_SNAME_SIZE,MED_SNAME_SIZE);
527     // suppress space at the end
528     int j;
529     for(j=MED_SNAME_SIZE-1;j>=0;j--)
530       if (myStringName[j] != ' ') break;
531     ptrGrid->_coordinate->_coordinateName[i]=string(myStringName,0,j+1);
532     for(j=MED_SNAME_SIZE-1;j>=0;j--)
533       if (myStringUnit[j] != ' ') break;
534     ptrGrid->_coordinate->_coordinateUnit[i]=string(myStringUnit,0,j+1);
535   }
536
537   string coordinateSystem = "UNDEFINED";
538
539   if( rep == med_2_3::MED_CARTESIAN) coordinateSystem = "CARTESIAN";
540   else if ( rep == med_2_3::MED_CYLINDRICAL) coordinateSystem = "CYLINDRICAL";
541   else if ( rep == med_2_3::MED_SPHERICAL) coordinateSystem = "SPHERICAL";
542
543   ptrGrid->_coordinate->setCoordinatesSystem(coordinateSystem);
544
545   END_OF_MED(LOC);
546 }
547
548 //=======================================================================
549 //function : getCOORDINATE
550 // A FAIRE : RENVOYER DU VOID
551 //=======================================================================
552 int  MED_MESH_RDONLY_DRIVER::getCOORDINATE()
553 {
554   const char * LOC = "MED_MESH_RDONLY_DRIVER::getCOORDINATE() : ";
555
556   BEGIN_OF_MED(LOC);
557
558   if (_status==MED_OPENED)
559   {
560     int err;
561     int MeshDimension;
562     int SpaceDimensionRead;
563     med_2_3::med_mesh_type meshTypepp3;
564     char meshDescription[MED_COMMENT_SIZE+1]="";
565     char dtunit[MED_LNAME_SIZE+1];
566     med_2_3::med_sorting_type sortTypepp3;
567     int nstepp3;
568     med_2_3::med_axis_type axtypepp3;
569     //
570     string tmp_nom_coord (MED_SNAME_SIZE*_ptrMesh->_spaceDimension+1,'\0');
571     string tmp_unit_coord(MED_SNAME_SIZE*_ptrMesh->_spaceDimension+1,'\0');
572     char * tmp_nom = (const_cast <char *> ( tmp_nom_coord.c_str())  );
573     char * tmp_unit= (const_cast <char *> ( tmp_unit_coord.c_str()) );
574     //
575     err=med_2_3::MEDmeshInfoByName(_medIdt,_meshName.c_str(),
576                                    &SpaceDimensionRead,&MeshDimension,
577                                    &meshTypepp3,meshDescription,
578                                    dtunit,&sortTypepp3,&nstepp3,
579                                    &axtypepp3,tmp_nom,tmp_unit);
580     int dtp3,itp3;
581     med_2_3::med_float ttpp3;
582     med_2_3::MEDmeshComputationStepInfo(_medIdt,_meshName.c_str(),1,&dtp3,&itp3,&ttpp3);
583
584     MESH* ptrMesh = dynamic_cast<MESH*>(_ptrMesh);
585
586     // Read the number of nodes used in the mesh <_meshName>
587     // to be able to create a COORDINATE object
588     med_2_3::med_bool chgtpp3,trsfpp3;
589     int NumberOfNodes = med_2_3::MEDmeshnEntity(_medIdt,_meshName.c_str(),
590                                                 dtp3,itp3,med_2_3::MED_NODE,MED_NONE,
591                                                 med_2_3::MED_COORDINATE,
592                                                 med_2_3::MED_NO_CMODE,
593                                                 &chgtpp3,&trsfpp3);
594     if ( NumberOfNodes <= MED_VALID )
595       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"The number of nodes |" << NumberOfNodes
596                                    << "| seems to be incorrect for the mesh : |" << _meshName << "|" ));
597     ptrMesh->_numberOfNodes = NumberOfNodes;
598
599     // create a COORDINATE object
600     if (ptrMesh->_coordinate)
601       delete ptrMesh->_coordinate;
602     ptrMesh->_coordinate = new COORDINATE(ptrMesh->_spaceDimension, NumberOfNodes, MED_EN::MED_FULL_INTERLACE);
603
604     med_2_3::med_axis_type rep=axtypepp3; // ATTENTION ---> DOIT ETRE INTEGRE DS MESH EF: FAIT NON?
605
606     err=MEDmeshNodeCoordinateRd(_medIdt,_ptrMesh->_name.c_str(),dtp3,itp3,med_2_3::MED_FULL_INTERLACE,const_cast<double *>(ptrMesh->_coordinate->_coordinate.get(MED_EN::MED_FULL_INTERLACE)));
607
608     if (err != MED_VALID)
609       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't read coordinates of the |" << NumberOfNodes
610                                    << "| nodes for the mesh : |" << _meshName
611                                    << "| of space dimension |" << ptrMesh->_spaceDimension
612                                    << "| with units names |"   << tmp_nom
613                                    << "| and units |"          << tmp_unit
614                                    << " |"));
615
616     for (int i=0;i<_ptrMesh->_spaceDimension;i++) {
617       string myStringName(tmp_nom_coord,i*MED_SNAME_SIZE,MED_SNAME_SIZE);
618       string myStringUnit(tmp_unit_coord,i*MED_SNAME_SIZE,MED_SNAME_SIZE);
619       // suppress space at the end
620       int j;
621       for(j=MED_SNAME_SIZE-1;j>=0;j--)
622         if (myStringName[j] != ' ') break;
623       ptrMesh->_coordinate->_coordinateName[i]=string(myStringName,0,j+1);
624       for(j=MED_SNAME_SIZE-1;j>=0;j--)
625         if (myStringUnit[j] != ' ') break;
626       ptrMesh->_coordinate->_coordinateUnit[i]=string(myStringUnit,0,j+1);
627     }
628
629     // Pourquoi le stocker sous forme de chaîne ?
630     switch (rep)
631     {
632     case med_2_3::MED_CARTESIAN :
633       {
634         ptrMesh->_coordinate->_coordinateSystem = "CARTESIAN";
635         break;
636       }
637     case med_2_3::MED_CYLINDRICAL :
638       {
639         ptrMesh->_coordinate->_coordinateSystem = "CYLINDRICAL";
640         break;
641       }
642     case med_2_3::MED_SPHERICAL  :
643       {
644         ptrMesh->_coordinate->_coordinateSystem = "SPHERICAL";
645         break;
646       }
647     default :
648       {
649         ptrMesh->_coordinate->_coordinateSystem = "UNDEFINED"; // ?Erreur ?
650         break;
651       }
652     }
653
654     // Read the unused optional node Names
655     if(MEDmeshnEntity(_medIdt,_ptrMesh->_name.c_str(),dtp3,itp3,med_2_3::MED_NODE,MED_NONE,med_2_3::MED_NAME,med_2_3::MED_NO_CMODE,&chgtpp3,&trsfpp3)>0)
656       MESSAGE_MED(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : WARNING : Nodes have names but we do not read them !");
657
658     // ??? Read the unused optional node Numbers ???
659     med_2_3::med_int * tmp_node_number = new med_2_3::med_int[NumberOfNodes];
660     if(MEDmeshnEntity(_medIdt,_ptrMesh->_name.c_str(),dtp3,itp3,med_2_3::MED_NODE,MED_NONE,med_2_3::MED_NUMBER,med_2_3::MED_NO_CMODE,&chgtpp3,&trsfpp3)>0)
661       {
662         err=MEDmeshEntityNumberRd(_medIdt,_ptrMesh->_name.c_str(),dtp3,itp3,med_2_3::MED_NODE,MED_NONE,tmp_node_number);
663
664         MESSAGE_MED(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : Nodes have numbers, we DO TAKE care of them !");
665         ptrMesh->_coordinate->_nodeNumber.set(NumberOfNodes);
666 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64)
667         for(med_2_3::med_int i2=0;i2<NumberOfNodes;i2++)
668           ptrMesh->_coordinate->_nodeNumber[i2]=(int)(tmp_node_number[i2]);
669 #else
670         memcpy((int*)ptrMesh->_coordinate->_nodeNumber,tmp_node_number,sizeof(int)*NumberOfNodes);
671 #endif
672
673       //////////////////////////////////////////////////////////////////////////////////////
674       ///  Modification pour prise en compte de la numérotation optionnelle des noeuds  ///
675       //////////////////////////////////////////////////////////////////////////////////////
676       ///
677       /// Calcule _optionnalToCanonicNodesNumbers de telle sorte que _optionnalToCanonicNodesNumbers[OptionnalNumber]==CanonicNumber
678
679       //        ptrMesh->_arePresentOptionnalNodesNumbers=1;
680       //        for (int canonicNumber=1;canonicNumber<=NumberOfNodes;canonicNumber++) ptrMesh->_optionnalToCanonicNodesNumbers[tmp_node_number[canonicNumber-1]]=canonicNumber;
681       // ICI RETOUR A LA NORMALE::: AUCUNE PRISE EN COMPTE D'UN NUMEROTATION OPTIONNEL
682       ptrMesh->_arePresentOptionnalNodesNumbers=0;
683     }
684     else ptrMesh->_arePresentOptionnalNodesNumbers=0;
685
686     //////////////////////////////////////////////////////////////////////////////////////
687
688     delete[] tmp_node_number;
689
690     END_OF_MED(LOC);
691     return MED_VALID;
692   }
693   return MED_ERROR;
694 }
695
696
697 int MED_MESH_RDONLY_DRIVER::getCONNECTIVITY()
698 {
699   const char * LOC = "MED_MESH_RDONLY_DRIVER::getCONNECTIVITY : ";
700   BEGIN_OF_MED(LOC);
701
702   if (_status==MED_OPENED)
703     {
704
705       int err = 0;
706       // read MED_CELL connectivity
707       CONNECTIVITY * Connectivity     = new CONNECTIVITY(MED_CELL);
708       Connectivity->_numberOfNodes    = _ptrMesh->getNumberOfNodes();   // EF : Pourquoi cet attribut est-il dans MESH et non dans COORDINATE ?
709
710       // Try to read nodal connectivity of the cells <Connectivity->_nodal>
711       // then try to read descending connectivity    <Connectivity->_descending>
712       // if neither nodal nor descending connectivity exists
713       // throw an exception.
714       err = getNodalConnectivity(Connectivity);
715       if (err!=MED_VALID)
716         {
717           Connectivity->_typeConnectivity = MED_DESCENDING;
718           err = getDescendingConnectivity(Connectivity);
719         }
720       else
721         getDescendingConnectivity(Connectivity); // we read it if there is one
722
723       if (err!=MED_VALID)
724         {
725           delete Connectivity;
726           throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "We could not read " <<
727                                        "any Connectivity"));
728         }
729
730       // commented since _ptrMesh->getMeshDimension() is based on connectivity
731       // which is not yet set
732 //       if (Connectivity->_entityDimension != _ptrMesh->getMeshDimension())
733 //         MESSAGE_MED(LOC << "Small mesh dimension problem on the med file mounted in memory : diim stored " << _ptrMesh->getMeshDimension() << " dim computed using the connectivity " << Connectivity->_entityDimension);
734
735       // At this point Connectivity->_typeConnectivity is either NODAL or DESCENDING
736       // If both connectivities are found Connectivity->_typeConnectivity is NODAL
737       // If space dimension is 3
738       // try to read the nodal connectivity of the faces <ConnectivityFace->_nodal> then
739       // try to read the descending connectivity <ConnectivityFace->_descending>
740       // if there is no descending connectivity and the CELLS are
741       // defined in descending mode then throw an exception
742
743       // PROVISOIRE : if we have some face or edge in MED_MAILLE, we don't read more. There could not be have face or edge !!!!
744
745       if(Connectivity->_constituent==NULL) {
746
747       if (Connectivity->_entityDimension == 3) {
748         MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DES FACES..." );
749         CONNECTIVITY * ConnectivityFace = new CONNECTIVITY(MED_EN::MED_FACE);
750         ConnectivityFace->_numberOfNodes    = _ptrMesh->getNumberOfNodes();
751         ConnectivityFace->_typeConnectivity = Connectivity->_typeConnectivity; // NODAL or DESCENDING
752         SCRUTE_MED(ConnectivityFace->_typeConnectivity);
753         if (Connectivity->_typeConnectivity == MED_DESCENDING) {
754           MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DESCENDANTE DES FACES" );
755           err = getDescendingConnectivity(ConnectivityFace);
756           if (err!=MED_VALID)
757             throw MEDEXCEPTION ( LOCALIZED(STRING(LOC) << "No FACE in descending connectivity"));
758           getNodalConnectivity(ConnectivityFace); // if any !
759         } else {
760           MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE NODALE DES FACES" );
761           err = getNodalConnectivity(ConnectivityFace);
762           if (err!=MED_VALID) { // or error ????? we are in NODAL mode.
763             err = getDescendingConnectivity(ConnectivityFace);
764           } else
765             getDescendingConnectivity(ConnectivityFace); // if any !
766         }
767         if (err!=MED_VALID) {
768           delete ConnectivityFace;
769           MESSAGE_MED(LOC<<"No FACE defined.");
770         } else {
771           MESSAGE_MED(LOC<<" SAUVEGARDE DE LA CONNECTIVITE DES FACES DANS L'OBJET CONNECTIVITY" );
772           delete Connectivity->_constituent;
773           Connectivity->_constituent=ConnectivityFace;
774         }
775       }
776
777       // read MED_EDGE connectivity
778       if (Connectivity->_entityDimension > 1) { // we are in 3 or 2D
779         MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DES ARRETES...." );
780         CONNECTIVITY * ConnectivityEdge = new CONNECTIVITY(MED_EDGE);
781         ConnectivityEdge->_numberOfNodes    = _ptrMesh->getNumberOfNodes();
782         ConnectivityEdge->_typeConnectivity = Connectivity->_typeConnectivity;
783         if (Connectivity->_typeConnectivity == MED_DESCENDING) {
784           MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DESCENDANTE DES ARRETES" );
785           err = getDescendingConnectivity(ConnectivityEdge);
786           if (err!=MED_VALID)
787             throw MEDEXCEPTION ( LOCALIZED(STRING(LOC) << "No EDGE in descending connectivity"));
788           getNodalConnectivity(ConnectivityEdge); // if any !
789         } else {
790           MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE NODALE DES ARRETES" );
791           err = getNodalConnectivity(ConnectivityEdge);
792           if (err!=MED_VALID) { // or error ????? we are in NODAL mode.
793             err = getDescendingConnectivity(ConnectivityEdge);
794           } else
795             getDescendingConnectivity(ConnectivityEdge); // if any !
796         }
797         if (err!=MED_VALID) {
798           delete ConnectivityEdge;
799           MESSAGE_MED(LOC<<"No EDGE defined.");
800         } else {
801           if (Connectivity->_entityDimension == 3)
802             if (Connectivity->_constituent != NULL)
803               Connectivity->_constituent->_constituent=ConnectivityEdge;
804             else
805               throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<< "EDGE defined but there are no FACE !"));
806           else { // IN 2D
807             MESSAGE_MED(LOC<<" SAUVEGARDE DE LA CONNECTIVITE DES ARETES DANS L'OBJET CONNECTIVITY" );
808             Connectivity->_constituent=ConnectivityEdge;
809           }
810         }
811       }
812       }
813       MESH* ptrMesh = dynamic_cast<MESH*>(_ptrMesh);
814       if (ptrMesh->_connectivity)
815         delete ptrMesh->_connectivity;
816       ptrMesh->_connectivity  = Connectivity;
817
818
819       END_OF_MED(LOC);
820       return MED_VALID;
821     }
822   return MED_ERROR;
823 }
824
825 int MED_MESH_RDONLY_DRIVER::getNodalConnectivity(CONNECTIVITY * Connectivity)
826 {
827   const char * LOC = "MED_MESH_RDONLY_DRIVER::getNodalConnectivity : ";
828   BEGIN_OF_MED(LOC);
829   med_2_3::med_bool chgtp3,trfp3;
830   med_2_3::med_err err;
831
832   if (_status==MED_OPENED)
833     {
834       int dtp3,itp3;
835       med_2_3::med_float ttpp3;
836       med_2_3::MEDmeshComputationStepInfo(_medIdt,_meshName.c_str(),1,&dtp3,&itp3,&ttpp3);
837       // Get the type of entity to work on (previously set in the Connectivity Object)
838       med_2_3::med_entity_type Entity = (med_2_3::med_entity_type) Connectivity->getEntity();
839
840       // Get the number of cells of each type & store it in <tmp_cells_count>.
841       vector<int> tmp_cells_count;
842       vector<CELLMODEL> tmp_cell_models; // models of present types
843       int i;
844       const list<MED_EN::medGeometryElement>& all_cell_type = meshEntities[ Connectivity->getEntity() ];
845       list<MED_EN::medGeometryElement>::const_iterator type_iter;
846       for ( type_iter = all_cell_type.begin(); type_iter != all_cell_type.end(); ++type_iter )
847         {
848           int nb_cells;
849           if ( med_2_3::med_geometry_type(*type_iter) != MED_POLYGON &&
850                med_2_3::med_geometry_type(*type_iter) != MED_POLYHEDRON )
851             nb_cells=med_2_3::MEDmeshnEntity(_medIdt,_ptrMesh->_name.c_str(),
852                                              dtp3,itp3,
853                                              med_2_3::MED_CELL,
854                                              med_2_3::med_geometry_type(*type_iter),
855                                              med_2_3::MED_CONNECTIVITY,med_2_3::MED_NODAL,
856                                              &chgtp3,&trfp3);
857           else if ( med_2_3::med_geometry_type(*type_iter) == MED_POLYGON )
858             nb_cells=med_2_3::MEDmeshnEntity(_medIdt,_ptrMesh->_name.c_str(),
859                                              dtp3,itp3,
860                                              med_2_3::MED_CELL,
861                                              MED_POLYGON,
862                                              med_2_3::MED_INDEX_NODE,
863                                              med_2_3::MED_NODAL,
864                                              &chgtp3,&trfp3) - 1;
865           else
866             nb_cells=med_2_3::MEDmeshnEntity(_medIdt,_ptrMesh->_name.c_str(),
867                                              dtp3,itp3,
868                                              med_2_3::MED_CELL,
869                                              MED_POLYHEDRON,
870                                              med_2_3::MED_INDEX_FACE,
871                                              med_2_3::MED_NODAL,
872                                              &chgtp3,&trfp3)-1;
873           /*med_2_3::MED_CONN,Entity,
874             med_2_3::med_geometry_type(*type_iter),med_2_3::MED_NOD);*/
875
876           // Get the greatest dimension of the cells : Connectivity->_entityDimension
877           // We suppose there is no cells used as faces in MED 2.2.x , this is forbidden !!!
878           // In version prior to 2.2.x, it is possible
879           if (nb_cells>0)
880             {
881               tmp_cells_count.push_back(nb_cells);
882               tmp_cell_models.push_back( CELLMODEL_Map::retrieveCellModel( *type_iter ));
883               Connectivity->_entityDimension=tmp_cell_models.back().getDimension();
884               Connectivity->_numberOfTypes++;
885             }
886         }
887
888       if (Connectivity->_numberOfTypes > 0)
889         {
890           // if MED version < 2.2.x, we read only entity with
891         // dimention = Connectivity->_entityDimension. Lesser dimension are face or edge !
892
893         med_2_3::med_int major, minor, release;
894
895         if ( med_2_3::MEDfileNumVersionRd(_medIdt, &major, &minor, &release) != 0 )
896           // error : we suppose we have not a good med file !
897           return MED_ERROR;
898
899         // we get MED version number
900         // If MED version is < 2.2 then the cells which dimension
901         // is lesser than the main dimension ( Connectivity->_entityDimension )
902         // are either faces or edges
903
904         vector<int> tmpEdgeCount, tmpFaceCount;
905         vector<MED_EN::medGeometryElement> edgeTypes, faceTypes;
906         if (Entity==med_2_3::MED_CELL)
907         {
908           Connectivity->_numberOfTypes=0;
909
910           for ( i=0;i<int(tmp_cell_models.size());i++)
911           {
912             int dimension = tmp_cell_models[i].getDimension();
913             if (Connectivity->_entityDimension == dimension)
914               Connectivity->_numberOfTypes++;
915             if (Connectivity->_entityDimension > dimension)
916             {
917               if (dimension == 2 )
918               {
919                 faceTypes.push_back( tmp_cell_models[i].getType() );
920                 tmpFaceCount.push_back( tmp_cells_count[i] );
921                 tmp_cells_count[i] = 0;
922               }
923               else if (dimension == 1 )
924                 {
925                   edgeTypes.push_back( tmp_cell_models[i].getType() );
926                   tmpEdgeCount.push_back( tmp_cells_count[i] );
927                   tmp_cells_count[i] = 0;
928                 }
929               else if (dimension == 0 )
930                 {
931                   tmp_cells_count[i] = 0;
932                 }
933             }
934           }
935         }
936
937         // Retrieve connectivity size of poly elements
938         med_2_3::med_int polygonConnSize, polyhedraFacesIndexSize, polyhedraConnSize;
939         int polyhedraConnSizeWithFaceSeparators;
940         if ( tmp_cell_models.back().getType() == MED_EN::MED_POLYGON ||
941              (!faceTypes.empty() && faceTypes.back() == MED_EN::MED_POLYGON ))
942           {
943             polygonConnSize = med_2_3::MEDmeshnEntity(_medIdt,_ptrMesh->_name.c_str(),
944                                                       dtp3,itp3,
945                                                       med_2_3::MED_CELL,
946                                                       MED_POLYGON,
947                                                       med_2_3::MED_CONNECTIVITY,
948                                                       med_2_3::MED_NODAL,
949                                                       &chgtp3,&trfp3);
950           }
951         if ( tmp_cell_models.back().getType() == MED_EN::MED_POLYHEDRA )
952           {
953             polyhedraFacesIndexSize=MEDmeshnEntity(_medIdt,_ptrMesh->_name.c_str(),
954                                                    dtp3,itp3,
955                                                    med_2_3::MED_CELL,
956                                                    MED_POLYHEDRON,
957                                                    med_2_3::MED_INDEX_NODE,
958                                                    med_2_3::MED_NODAL,
959                                                    &chgtp3,&trfp3);
960             polyhedraConnSize=MEDmeshnEntity(_medIdt,_ptrMesh->_name.c_str(),
961                                              dtp3,itp3,
962                                              med_2_3::MED_CELL,
963                                              MED_POLYHEDRON,
964                                              med_2_3::MED_CONNECTIVITY,
965                                              med_2_3::MED_NODAL,
966                                              &chgtp3,&trfp3);
967
968             int nbPolyherda = tmp_cells_count.back();
969             int nbFaces     = polyhedraFacesIndexSize - 1;
970             // connectivity of each but last face of each polyhedron ends with -1
971             polyhedraConnSizeWithFaceSeparators = polyhedraConnSize + nbFaces - nbPolyherda;
972           }
973
974         // bloc to read CELL :
975         {
976           // Prepare an array of indexes on the different cell types to create a MEDSKYLINEARRAY
977           // We use <tmp_cells_count> to calculate <Connectivity->_count> then we release it
978           Connectivity->_geometricTypes = new MED_EN::medGeometryElement [Connectivity->_numberOfTypes]; // Double emploi pour des raisons pratiques
979           Connectivity->_type           = new CELLMODEL                  [Connectivity->_numberOfTypes]; //
980           if(Connectivity->_count) delete [] Connectivity->_count;
981           Connectivity->_count          = new int                        [Connectivity->_numberOfTypes+1];
982           Connectivity->_count[0]       = 1;
983
984           int size = 0;
985           int typeNumber=1;
986           vector<int> connSizeByType;
987           for ( i=0; i < (int)tmp_cells_count.size(); i++)
988           { // no point1 cell type (?)
989             if ( !tmp_cells_count[i] ) continue; // faces or edges
990
991             Connectivity->_count[typeNumber]=Connectivity->_count[typeNumber-1]+tmp_cells_count[i];
992
993             Connectivity->_type[typeNumber-1] = tmp_cell_models[i];
994
995             Connectivity->_geometricTypes[typeNumber-1] = tmp_cell_models[i].getType();
996
997             // probleme avec les mailles de dimension < a dimension du maillage :
998             // Il faut oter le zero a la lecture est le remettre a l'ecriture : ce n'est pas fait !!!!!
999             // On interdit ce cas pour l'instant !!!
1000
1001             switch (tmp_cell_models[i].getType() )
1002             {
1003             case MED_EN::MED_POLYGON:
1004               connSizeByType.push_back( polygonConnSize ); break;
1005             case MED_EN::MED_POLYHEDRA:
1006               connSizeByType.push_back( polyhedraConnSizeWithFaceSeparators ); break;
1007             default:
1008               connSizeByType.push_back
1009                 (tmp_cells_count[i] * tmp_cell_models[i].getNumberOfNodes() );
1010             }
1011             size += connSizeByType.back();
1012             typeNumber++;
1013             MESSAGE_MED(LOC << Connectivity->_count[typeNumber-1]-1 << " cells of type "
1014                         << tmp_cell_models[i].getName() );
1015           }
1016
1017           // Creation of the MEDSKYLINEARRAY
1018           PointerOf <int> NodalValue(size);
1019           PointerOf <int> NodalIndex(Connectivity->_count[Connectivity->_numberOfTypes]);
1020           NodalIndex[0]=1;
1021
1022           // Fill the MEDSKYLINEARRAY by reading the MED file.
1023           int j=0;
1024           for ( i=0;i<Connectivity->_numberOfTypes;i++)
1025           {
1026             int tmp_numberOfCells = Connectivity->_count[i+1]-Connectivity->_count[i];
1027             PointerOf< med_2_3::med_int > tmp_ConnectivityArray( connSizeByType[i] );
1028
1029             switch ( Connectivity->_geometricTypes[i] )
1030             {
1031             case MED_EN::MED_POLYGON:
1032               {
1033                 PointerOf <med_2_3::med_int> PolygonsConnIndex( tmp_numberOfCells+1 );
1034                 err = med_2_3::MEDmeshPolygonRd(_medIdt,_ptrMesh->_name.c_str(),
1035                                                dtp3,itp3,
1036                                                med_2_3::MED_CELL,
1037                                                med_2_3::MED_NODAL,
1038                                                PolygonsConnIndex,
1039                                                tmp_ConnectivityArray);
1040                 if (err != MED_VALID)
1041                 {
1042                   MESSAGE_MED(LOC<<": MEDpolygoneConnLire returns "<<err);
1043                   return MED_ERROR;
1044                 }
1045                 int* polyindex = (int*)NodalIndex + Connectivity->_count[i] - 1;
1046                 int delta = polyindex[0] - PolygonsConnIndex[0];
1047                 for ( j=0; j<=tmp_numberOfCells; j++)
1048                   polyindex[j]= delta + PolygonsConnIndex[ j ];
1049                 break;
1050               }
1051             case MED_EN::MED_POLYHEDRA:
1052               {
1053                 PointerOf< med_2_3::med_int> FacesIndex( polyhedraFacesIndexSize );
1054                 PointerOf< med_2_3::med_int> PolyhedronIndex( tmp_numberOfCells+1 );
1055                 err = med_2_3::MEDmeshPolyhedronRd(_medIdt,_ptrMesh->_name.c_str(),
1056                                                   dtp3,itp3,
1057                                                   med_2_3::MED_CELL,
1058                                                   med_2_3::MED_NODAL,
1059                                                   PolyhedronIndex,
1060                                                   FacesIndex,
1061                                                   tmp_ConnectivityArray);
1062                 if (err != MED_VALID)
1063                 {
1064                   MESSAGE_MED(LOC<<": MEDpolyedreConnLire returns "<<err);
1065                   return MED_ERROR;
1066                 }
1067                 // insert face separators
1068                 int* polyindex = NodalIndex + Connectivity->_count[i] - 1;
1069                 int k = NodalIndex[ Connectivity->_count[i]-1 ] - 1;
1070                 for ( j=0; j<tmp_numberOfCells; j++)
1071                 {
1072                   int k0 = k;
1073                   for ( int iface = PolyhedronIndex[j]; iface < PolyhedronIndex[j+1]; ++iface)
1074                   {
1075                     for ( int inode = FacesIndex[iface-1]; inode < FacesIndex[iface]; ++inode)
1076                       NodalValue[k++] = tmp_ConnectivityArray[inode-1];
1077                     if ( iface+1 < PolyhedronIndex[j+1] )
1078                       NodalValue[k++] = -1;
1079                   }
1080                   polyindex[j+1] = polyindex[j] + k - k0;
1081                 }
1082                 continue; // no need to copy tmp_ConnectivityArray - already done
1083                 //break;
1084               }
1085             default:
1086               err = med_2_3::MEDmeshElementConnectivityRd(_medIdt,_ptrMesh->_name.c_str(),
1087                                               dtp3,itp3,
1088                                               med_2_3::MED_CELL,
1089                                               med_2_3::med_geometry_type(Connectivity->_geometricTypes[i]),
1090                                               med_2_3::MED_NODAL,
1091                                               med_2_3::MED_FULL_INTERLACE,
1092                                               tmp_ConnectivityArray
1093                                               );
1094               if ( err != MED_VALID)
1095               {
1096                 MESSAGE_MED(LOC<<": MEDconnLire returns "<<err);
1097                 return MED_ERROR;
1098               }
1099               int NumberOfNodeByCell = Connectivity->_type[i].getNumberOfNodes();
1100               // initialise index
1101               for ( j=Connectivity->_count[i]; j<Connectivity->_count[i+1];j++)
1102                 NodalIndex[j]=NodalIndex[j-1]+NumberOfNodeByCell;
1103             }
1104
1105             // version originale sans prise en compte des numeros optionnels
1106             //
1107             int * ConnectivityArray = NodalValue + NodalIndex[Connectivity->_count[i]-1]-1;
1108             for ( j=0; j<connSizeByType[i]; j++)
1109               ConnectivityArray[j] = tmp_ConnectivityArray[j];
1110
1111             //////////////////////////////////////////////////////////////////////////////
1112             // Modification pour prise en compte de la numerotation optionnelle des noeuds ///
1113             //////////////////////////////////////////////////////////////////////////////
1114             //
1115             // Renumerote le tableau temporaire tmp_ConnectivityArray
1116             // en utilisant _optionnalToCanonicNodesNumbers
1117             // Le traitement est identique a la version originelle
1118             // s'il n'y a pas de numerotation optionnelle
1119             //
1120             //if (_ptrMesh->_arePresentOptionnalNodesNumbers==1)
1121             //{
1122             //  for ( j=0; j<tmp_numberOfCells; j++) for (int k=0; k<NumberOfNodeByCell; k++)
1123             //    ConnectivityArray[j*NumberOfNodeByCell+k] = _ptrMesh->
1124             //      _optionnalToCanonicNodesNumbers[tmp_ConnectivityArray[j*(NumberOfNodeByCell+multi)+k]];
1125             //}
1126             //else
1127             //{
1128             //  for ( j=0; j<tmp_numberOfCells; j++) for (int k=0; k<NumberOfNodeByCell; k++)
1129             //    ConnectivityArray[j*NumberOfNodeByCell+k] =
1130             //      tmp_ConnectivityArray[j*(NumberOfNodeByCell+multi)+k];
1131             //}
1132             ////////////////////////////////////////////////////////////////////////////
1133
1134           }
1135
1136           Connectivity->_nodal = new MEDSKYLINEARRAY(Connectivity->_count[Connectivity->_numberOfTypes]-1,
1137                                                      size,
1138                                                      NodalIndex,
1139                                                      NodalValue);
1140
1141         } // end of bloc to read CELL
1142
1143         // Get Face if any
1144         // ===============
1145         if (!faceTypes.empty())
1146         {
1147           // Create a CONNECTIVITY constituent to put in the top level CONNECTIVITY recursive class
1148           CONNECTIVITY * constituent = new CONNECTIVITY(faceTypes.size(),MED_EN::MED_FACE);
1149           constituent->_numberOfNodes = _ptrMesh->getNumberOfNodes();
1150           constituent->_entityDimension = 2;
1151           constituent->_count[0]=1;
1152
1153           // In order to create the MEDSKYLINEARRAY of the constituent object we need :
1154           // 1:
1155           // To initialize the _count array of the constituent object
1156           // (containning cumulated face count by geometric type)
1157           // _count[0]=1 and _count[_numberOfTypes] give the size of NodalIndex
1158           // 2:
1159           // To calculate the total number of face nodes whatever the geometric type is.
1160           // The result is the size of the array containning all the nodes : NodalValue
1161           // 3 :
1162           // To calculate the starting indexes of the different face types in NodalValue,
1163           // this is the NodalIndex array.
1164
1165           int size = 0;
1166           vector<int> connSizeByType;
1167           for ( i=0; i < (int)faceTypes.size(); i++)
1168           {
1169             constituent->_count[i+1] = constituent->_count[i] + tmpFaceCount[i];
1170             constituent->_type[i] = CELLMODEL_Map::retrieveCellModel( faceTypes[i] );
1171             constituent->_geometricTypes[i] = faceTypes[i];
1172
1173             if ( faceTypes[i] == MED_EN::MED_POLYGON )
1174               connSizeByType.push_back( polygonConnSize );
1175             else
1176               connSizeByType.push_back( tmpFaceCount[i] * constituent->_type[i].getNumberOfNodes());
1177             size += connSizeByType.back();
1178           }
1179
1180           // Creation of the MEDSKYLINEARRAY
1181           PointerOf<int> NodalValue (size);
1182           PointerOf<int> NodalIndex (constituent->_count[constituent->_numberOfTypes]);
1183           NodalIndex[0]=1;
1184
1185           // Fill the MEDSKYLINEARRAY by reading the MED file.
1186           for ( i=0; i<constituent->_numberOfTypes; i++)
1187           {
1188             int NumberOfNodeByFace = constituent->_type[i].getNumberOfNodes();
1189
1190             // Il faut ajouter 1 pour le zero a la lecture !!!
1191             // ATTENTION UNIQUEMENT POUR MED < 2.2.x
1192             PointerOf< med_2_3::med_int> tmp_constituentArray;
1193
1194             MESSAGE_MED(LOC << "Med file version used here " << major << " " << minor << " " << release);
1195
1196             if ((major == 2) && (minor <= 1))
1197               tmp_constituentArray.set( connSizeByType[i] + tmpFaceCount[i] );
1198             else if ((major == 2) && (minor >= 2))
1199             {
1200               tmp_constituentArray.set( connSizeByType[i] );
1201               MESSAGE_MED(LOC<<": WE ARE USING MED2.2 so there is no +1 for calculating the size of  tmp_constituentArray !");
1202             }
1203             else
1204               tmp_constituentArray.set( connSizeByType[i] );
1205
1206             if ( constituent->_geometricTypes[i] == MED_EN::MED_POLYGON )
1207             {
1208               PointerOf< med_2_3::med_int> PolygonsConnIndex( tmpFaceCount[i]+1 );
1209               err = med_2_3::MEDmeshPolygonRd(_medIdt,_ptrMesh->_name.c_str(),
1210                                                    dtp3,itp3,
1211                                                    med_2_3::MED_CELL,
1212                                                    med_2_3::MED_NODAL,
1213                                                    PolygonsConnIndex,
1214                                                    tmp_constituentArray);
1215
1216               if (err != MED_VALID)
1217               {
1218                 MESSAGE_MED(LOC<<": MEDpolygoneConnLire returns "<<err);
1219                 delete constituent;
1220                 return MED_ERROR;
1221               }
1222               int* polyindex = (int*)NodalIndex + constituent->_count[i] - 1;
1223               int delta = polyindex[0] - PolygonsConnIndex[0];
1224               for ( int j=0; j<=tmpFaceCount[i]; j++)
1225                 polyindex[j]= delta + PolygonsConnIndex[ j ];
1226             }
1227             else
1228             {
1229               med_2_3::med_geometry_type med_type =
1230                 (med_2_3::med_geometry_type) constituent->_type[i].getType();
1231               err = med_2_3::MEDmeshElementConnectivityRd(_medIdt,_ptrMesh->_name.c_str(),
1232                                               dtp3,itp3,
1233                                               med_2_3::MED_CELL,
1234                                               med_type,
1235                                               med_2_3::MED_NODAL,
1236                                               med_2_3::MED_FULL_INTERLACE,
1237                                               tmp_constituentArray
1238                                               );
1239               if ( err != MED_VALID)
1240               {
1241                 MESSAGE_MED(LOC<<": MEDconnLire returns "<<err);
1242                 delete constituent;
1243                 return MED_ERROR;
1244               }
1245               // initialise NodalIndex
1246               for (int j=constituent->_count[i]; j<constituent->_count[i+1];j++)
1247                 NodalIndex[j]=NodalIndex[j-1]+NumberOfNodeByFace;
1248             }
1249
1250             int tmp_numberOfFaces = constituent->_count[i+1]-constituent->_count[i];
1251
1252             int * constituentArray = NodalValue + NodalIndex[constituent->_count[i]-1]-1;
1253
1254             MESSAGE_MED(LOC << "Med file version used here " << major << " " << minor << " " << release);
1255             if ((major == 2) && (minor <= 1))
1256               for (int j=0; j<tmp_numberOfFaces; j++)
1257                 for (int k=0; k<NumberOfNodeByFace; k++)
1258                   constituentArray[j*NumberOfNodeByFace+k]=tmp_constituentArray[j*(NumberOfNodeByFace+1)+k];
1259             else if (((major == 2) && (minor >= 2)) || (major > 2))
1260               for ( int j = 0; j < connSizeByType[i]; ++j )
1261                 constituentArray[j]=tmp_constituentArray[j];
1262           }
1263
1264           constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1,
1265                                                     size,
1266                                                     NodalIndex,
1267                                                     NodalValue);
1268           Connectivity->_constituent = constituent;
1269         }
1270
1271         // get Edge if any
1272         // ===============
1273         if ( !edgeTypes.empty() )
1274         {
1275           CONNECTIVITY * constituent = new CONNECTIVITY(tmpEdgeCount.size() ,MED_EDGE);
1276           constituent->_numberOfNodes = _ptrMesh->getNumberOfNodes();
1277           constituent->_entityDimension = 1;
1278           constituent->_count[0]=1;
1279
1280           int size = 0;
1281           for ( i=0; i<(int)edgeTypes.size(); i++)
1282           {
1283             constituent->_count[i+1]=constituent->_count[i]+tmpEdgeCount[i];
1284             constituent->_type[i]=CELLMODEL_Map::retrieveCellModel( edgeTypes[i] );
1285             constituent->_geometricTypes[i] = edgeTypes[i];
1286
1287             size+=tmpEdgeCount[i]*constituent->_type[i].getNumberOfNodes();
1288           }
1289
1290           // Creation of the MEDSKYLINEARRAY
1291           PointerOf< int > NodalValue( size );
1292           PointerOf< int > NodalIndex( constituent->_count[constituent->_numberOfTypes] );
1293           NodalIndex[0]=1;
1294
1295           // Fill the MEDSKYLINEARRAY by reading the MED file.
1296           for ( i=0; i<constituent->_numberOfTypes; i++)
1297           {
1298             med_2_3::med_geometry_type med_type =
1299               (med_2_3::med_geometry_type) constituent->_type[i].getType();
1300             int NumberOfNodeByEdge = constituent->_type[i].getNumberOfNodes();
1301
1302             // initialise index
1303             for (int j=constituent->_count[i]; j<constituent->_count[i+1];j++)
1304               NodalIndex[j]=NodalIndex[j-1]+NumberOfNodeByEdge;
1305
1306             int tmp_numberOfEdges = constituent->_count[i+1]-constituent->_count[i];
1307             // Il faut ajouter 1 pour le zero a la lecture !!!
1308
1309             // ATTENTION UNIQUEMENT POUR MED < 2.2.x
1310             med_2_3::med_int * tmp_constituentArray = NULL;
1311
1312             MESSAGE_MED(LOC << "Med file version used here " << major << " " << minor << " " << release);
1313
1314             if ((major == 2) && (minor <= 1))
1315               tmp_constituentArray = new med_2_3::med_int[(NumberOfNodeByEdge+1)*tmp_numberOfEdges];
1316             else if ((major == 2 && minor >= 2) || ( major > 2 ))
1317             {
1318               tmp_constituentArray = new med_2_3::med_int[NumberOfNodeByEdge*tmp_numberOfEdges];
1319               MESSAGE_MED(LOC<<": WE ARE USING MED2.2 so there is no +1 for calculating the size of  tmp_constituentArray !");
1320             }
1321
1322             err = med_2_3::MEDmeshElementConnectivityRd(_medIdt,_ptrMesh->_name.c_str(),
1323                                               dtp3,itp3,
1324                                               med_2_3::MED_CELL,
1325                                               med_type,
1326                                               med_2_3::MED_NODAL,
1327                                               med_2_3::MED_FULL_INTERLACE,
1328                                               tmp_constituentArray
1329                                               );
1330             if ( err != MED_VALID)
1331             {
1332               MESSAGE_MED(LOC<<": MEDconnLire returns "<<err);
1333               delete constituent;
1334               delete[] tmp_constituentArray;
1335               return MED_ERROR;
1336             }
1337
1338             int * constituentArray = NodalValue + NodalIndex[constituent->_count[i]-1]-1;
1339
1340             // version originale sans prise en compte des numéros optionnels
1341             //
1342             int multi = 0; // quand est-ce que multi vaut 1 ?? en MED-fichier < 2.2 ??
1343             MESSAGE_MED(LOC << "Med file version used here " << major << " " << minor << " " << release);
1344
1345             if ((major == 2) && (minor <= 1))
1346               for (int j=0; j<tmp_numberOfEdges; j++)
1347                 for (int k=0; k<NumberOfNodeByEdge; k++)
1348                   constituentArray[j*NumberOfNodeByEdge+k] =
1349                     tmp_constituentArray[j*(NumberOfNodeByEdge+multi)+k];
1350             else if ((major == 2 && minor >= 2) || (major > 2))
1351               for (int j=0; j<tmp_numberOfEdges; j++)
1352                 for (int k=0; k<NumberOfNodeByEdge; k++)
1353                   constituentArray[j*NumberOfNodeByEdge+k] = tmp_constituentArray[j*(NumberOfNodeByEdge)+k];
1354
1355             //////////////////////////////////////////////////////////////////////////////////////
1356             ///  Modification pour prise en compte de la numérotation optionnelle des noeuds   ///
1357             //////////////////////////////////////////////////////////////////////////////////////
1358             ///
1359             /// Rénumérote le tableau temporaire tmp_constituentArray en utilisant
1360             /// _optionnalToCanonicNodesNumbers
1361             /// Le traitement est identique à la version originelle
1362             /// s'il n'y a pas de numérotation optionnelle
1363             //
1364             //if (_ptrMesh->_arePresentOptionnalNodesNumbers)
1365             //{
1366             //  for (int j=0; j<tmp_numberOfEdges; j++) for (int k=0; k<NumberOfNodeByEdge; k++)
1367             //    constituentArray[j*NumberOfNodeByEdge+k] = _ptrMesh->
1368             //      _optionnalToCanonicNodesNumbers[tmp_constituentArray[j*(NumberOfNodeByEdge+1)+k]];
1369             //}
1370             //else
1371             //{
1372             //  for (int j=0; j<tmp_numberOfEdges; j++) for (int k=0; k<NumberOfNodeByEdge; k++)
1373             //    constituentArray[j*NumberOfNodeByEdge+k]=tmp_constituentArray[j*(NumberOfNodeByEdge+1)+k];
1374             //}
1375             //////////////////////////////////////////////////////////////////////////////////////
1376
1377             delete[] tmp_constituentArray;
1378           }
1379
1380           constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1,
1381                                                     size,
1382                                                     NodalIndex,
1383                                                     NodalValue);
1384
1385           if (Connectivity->_entityDimension == 3)
1386           {
1387             if (Connectivity->_constituent==NULL)
1388               throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Edges are defined but there are no Faces !"));
1389             Connectivity->_constituent->_constituent = constituent;
1390           } else
1391             Connectivity->_constituent = constituent;
1392         }
1393
1394       }
1395
1396       // If there is no nodal connectivity, we return MED_ERROR !
1397       if (Connectivity->_numberOfTypes == 0)
1398         return MED_ERROR;
1399       else
1400         return MED_VALID;
1401     }
1402   return MED_ERROR;
1403 }
1404
1405 int  MED_MESH_RDONLY_DRIVER::getFAMILY()
1406 {
1407   const char * LOC = "MED_MESH_RDONLY_DRIVER::getFAMILY() : ";
1408   BEGIN_OF_MED(LOC);
1409
1410   if (_status==MED_OPENED)
1411   {
1412     int err = 0;
1413
1414     int * MEDArrayNodeFamily = NULL;
1415     int ** MEDArrayCellFamily = NULL;
1416     int ** MEDArrayFaceFamily = NULL;
1417     int ** MEDArrayEdgeFamily = NULL;
1418
1419     // NODE :
1420     MEDArrayNodeFamily = new int[_ptrMesh->getNumberOfNodes()];
1421
1422     err = getNodesFamiliesNumber(MEDArrayNodeFamily);
1423     // error only if (_status!=MED_OPENED), other case exeception !
1424     // CELL
1425
1426     MESSAGE_MED(LOC << "error returned from getNodesFamiliesNumber " << err);
1427
1428     MEDArrayCellFamily = new int* [_ptrMesh->getNumberOfTypes(MED_CELL)];
1429     // ET SI IL N'Y A PAS DE CELLS ?
1430
1431     const medGeometryElement * myTypes = _ptrMesh->getTypes(MED_CELL);
1432     for (int i=0;i<_ptrMesh->getNumberOfTypes(MED_CELL);i++)
1433       MEDArrayCellFamily[i] = new
1434         int[_ptrMesh->getNumberOfElements(MED_CELL,myTypes[i])];
1435
1436     err = getCellsFamiliesNumber(MEDArrayCellFamily,MED_CELL);
1437     MESSAGE_MED(LOC << "error returned from getCellsFamiliesNumber for Cells " << err);
1438
1439     if (_ptrMesh->getNumberOfElements( MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS ))
1440     {
1441       // FACE
1442       MEDArrayFaceFamily = new int* [_ptrMesh->getNumberOfTypes(MED_FACE)];
1443
1444       myTypes = _ptrMesh->getTypes(MED_FACE);
1445       for (int i=0;i<_ptrMesh->getNumberOfTypes(MED_FACE);i++)
1446         MEDArrayFaceFamily[i] = new int[ _ptrMesh->getNumberOfElements( MED_FACE,myTypes[i])];
1447
1448       err = getCellsFamiliesNumber(MEDArrayFaceFamily,MED_FACE);
1449       MESSAGE_MED(LOC << "error returned from getCellsFamiliesNumber for Faces " << err);
1450     }
1451     if (_ptrMesh->getNumberOfElements( MED_EN::MED_EDGE, MED_EN::MED_ALL_ELEMENTS))
1452     {
1453       // EDGE in 3D or 2D
1454       MEDArrayEdgeFamily = new int* [_ptrMesh->getNumberOfTypes(MED_EDGE)];
1455
1456       const medGeometryElement *myTypes2 = _ptrMesh->getTypes(MED_EDGE);
1457       for (int i=0;i<_ptrMesh->getNumberOfTypes(MED_EDGE);i++)
1458         MEDArrayEdgeFamily[i] = new
1459           int[_ptrMesh->getNumberOfElements(MED_EDGE,myTypes2[i])];
1460
1461       err = getCellsFamiliesNumber(MEDArrayEdgeFamily,MED_EDGE);
1462
1463       MESSAGE_MED(LOC << "error returned from getCellsFamiliesNumber for Edges " << err);
1464     }
1465
1466     int NumberOfFamilies = med_2_3::MEDnFamily(_medIdt,_meshName.c_str());
1467
1468     if ( NumberOfFamilies < 1 ) // at least family 0 must exist
1469       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"There is no FAMILY, FAMILY 0 must exists" ));
1470
1471     SCRUTE_MED(NumberOfFamilies);
1472
1473     vector<FAMILY*> &NodeFamilyVector = _ptrMesh->_familyNode;
1474     vector<FAMILY*> &CellFamilyVector = _ptrMesh->_familyCell;
1475     vector<FAMILY*> &FaceFamilyVector = _ptrMesh->_familyFace;
1476     vector<FAMILY*> &EdgeFamilyVector = _ptrMesh->_familyEdge;
1477
1478     int numberOfNodesFamilies = 0;
1479     int numberOfCellsFamilies = 0;
1480     int numberOfFacesFamilies = 0;
1481     int numberOfEdgesFamilies = 0;
1482
1483
1484     for (int i=0;i<NumberOfFamilies;i++)
1485     {
1486 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64)
1487       med_2_3::med_int tmp_NumberOfAttributes = med_2_3::MEDnFamily23Attribute(_medIdt,_meshName.c_str(),i+1);
1488       med_2_3::med_int NumberOfAttributes = tmp_NumberOfAttributes;
1489 #else
1490       int NumberOfAttributes = med_2_3::MEDnFamily23Attribute(_medIdt,_meshName.c_str(),(i+1));
1491 #endif
1492
1493       if (NumberOfAttributes < 0)
1494         throw MEDEXCEPTION("MED_MESH_RDONLY_DRIVER::getFAMILY() : NumberOfAttributes" );
1495
1496 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64)
1497       med_2_3::med_int tmp_NumberOfGroups = med_2_3::MEDnFamilyGroup(_medIdt,_meshName.c_str(),i+1);
1498       int NumberOfGroups = tmp_NumberOfGroups;
1499 #else
1500       int NumberOfGroups = med_2_3::MEDnFamilyGroup(_medIdt,_meshName.c_str(),i+1);
1501 #endif
1502
1503       if (NumberOfGroups < 0)
1504         throw MEDEXCEPTION("MED_MESH_RDONLY_DRIVER::getFAMILY() : NumberOfGroups" );
1505
1506       int FamilyIdentifier;
1507       string FamilyName(MED_NAME_SIZE,'\0');
1508       // 0020071: Crash of V4_1_4rc2 (of testMedMemGeneral.py)
1509       // Pb with Mistrat_import22.med: it's zero family has non-empty AttributesIdentifier's and
1510       // AttributesValues' but MEDnAttribut() returns 0 (0 is hardcoded for zero family).
1511       // So we allocate nothing but MEDfamInfo() reads file contents so overwritting
1512       // stranger's memory. Stupid solution: allocate more than MEDnAttribut()
1513       const int iSafe = 10;
1514       int *  AttributesIdentifier = new int[NumberOfAttributes+iSafe];
1515       int *  AttributesValues     = new int[NumberOfAttributes+iSafe];
1516       string AttributesDescription(MED_COMMENT_SIZE*(NumberOfAttributes+iSafe),' ');
1517       string GroupsNames(MED_LNAME_SIZE*NumberOfGroups+1,'\0');
1518 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64)
1519       med_2_3::med_int tmp_FamilyIdentifier;
1520       med_2_3::med_int *  tmp_AttributesIdentifier = new med_2_3::med_int[NumberOfAttributes+iSafe];
1521       med_2_3::med_int *  tmp_AttributesValues     = new med_2_3::med_int[NumberOfAttributes+iSafe];
1522
1523       err=med_2_3::MEDfamily23Info(_medIdt,_meshName.c_str(),i+1,const_cast <char *>(FamilyName.c_str()),
1524                                    tmp_AttributesIdentifier,tmp_AttributesValues,const_cast <char *>(AttributesDescription.c_str()),&tmp_FamilyIdentifier,const_cast <char *>(GroupsNames.c_str()));
1525
1526       FamilyIdentifier = tmp_FamilyIdentifier;
1527       int ii;
1528       for ( ii = 0; ii < NumberOfAttributes; ii++ ) {
1529         AttributesIdentifier[ii] = tmp_AttributesIdentifier[ii];
1530         AttributesValues[ii] = tmp_AttributesValues[ii];
1531       }
1532       NumberOfAttributes = tmp_NumberOfAttributes;
1533       NumberOfGroups = tmp_NumberOfGroups;
1534       delete [] tmp_AttributesIdentifier;
1535       delete [] tmp_AttributesValues;
1536 #else
1537       err = med_2_3::MEDfamily23Info(_medIdt,_meshName.c_str(),i+1,const_cast <char *>(FamilyName.c_str()),
1538                                      AttributesIdentifier,AttributesValues,const_cast <char *>(AttributesDescription.c_str()),&FamilyIdentifier,const_cast <char *>(GroupsNames.c_str()));
1539 #endif
1540
1541
1542       SCRUTE_MED(GroupsNames);
1543       SCRUTE_MED(FamilyName);
1544       SCRUTE_MED(err);
1545       SCRUTE_MED(i);
1546
1547       if (err != MED_VALID)
1548         throw MEDEXCEPTION("MED_MESH_RDONLY_DRIVER::getFAMILY() : ERROR when get FAMILY informations" );
1549
1550       if (FamilyIdentifier != 0 )
1551       {
1552         FAMILY * Family = new FAMILY(_ptrMesh,FamilyIdentifier,FamilyName,
1553                                      NumberOfAttributes,
1554                                      AttributesIdentifier,
1555                                      AttributesValues,
1556                                      AttributesDescription,
1557                                      NumberOfGroups,GroupsNames,
1558                                      MEDArrayNodeFamily,
1559                                      MEDArrayCellFamily,
1560                                      MEDArrayFaceFamily,
1561                                      MEDArrayEdgeFamily);
1562
1563         // All good ?
1564         // if nothing found, delete Family
1565
1566         /*! \todo TODO : once unit tests are ready, check that there is no side effect
1567           and let the driver read empty families by removing the if case of the
1568           few following lines */
1569
1570         if (Family->getNumberOfTypes() == 0)
1571         {
1572           MESSAGE_MED(LOC<<"Nothing found for family "<<FamilyName<<
1573                       " : skip");
1574           Family->removeReference();
1575         }
1576         else
1577           switch (Family->getEntity())
1578           {
1579           case MED_EN::MED_NODE :
1580             _ptrMesh->removeReference();
1581             NodeFamilyVector.push_back(Family);
1582             numberOfNodesFamilies++;
1583             break;
1584           case MED_EN::MED_CELL :
1585             _ptrMesh->removeReference();
1586             CellFamilyVector.push_back(Family);
1587             numberOfCellsFamilies++;
1588             break;
1589           case MED_EN::MED_FACE :
1590             _ptrMesh->removeReference();
1591             FaceFamilyVector.push_back(Family);
1592             numberOfFacesFamilies++;
1593             break;
1594           case MED_EN::MED_EDGE :
1595             _ptrMesh->removeReference();
1596             EdgeFamilyVector.push_back(Family);
1597             numberOfEdgesFamilies++;
1598             break;
1599           }
1600       }
1601
1602       delete [] AttributesIdentifier;
1603       delete [] AttributesValues;
1604     }
1605
1606     if (MEDArrayNodeFamily != NULL)
1607       delete[] MEDArrayNodeFamily;
1608
1609     if (MEDArrayCellFamily != NULL)
1610     {
1611       for (int i=0; i<_ptrMesh->getNumberOfTypes(MED_CELL); i++)
1612         delete[] MEDArrayCellFamily[i];
1613       delete[] MEDArrayCellFamily;
1614     }
1615
1616     if (MEDArrayFaceFamily != NULL)
1617     {
1618       for (int i=0; i<_ptrMesh->getNumberOfTypes(MED_FACE); i++)
1619         delete[] MEDArrayFaceFamily[i];
1620       delete[] MEDArrayFaceFamily;
1621     }
1622
1623     if (MEDArrayEdgeFamily != NULL)
1624     {
1625       for (int i=0; i<_ptrMesh->getNumberOfTypes(MED_EDGE); i++)
1626         delete[] MEDArrayEdgeFamily[i];
1627       delete[] MEDArrayEdgeFamily;
1628     }
1629
1630     END_OF_MED(LOC);
1631     return MED_VALID;
1632   }
1633
1634   return MED_ERROR;
1635 }
1636
1637 int  MED_MESH_RDONLY_DRIVER::getNodesFamiliesNumber(int * MEDArrayNodeFamily)
1638 {
1639   const char * LOC = "MED_MESH_RDONLY_DRIVER::getNodesFamiliesNumber() : ";
1640
1641   BEGIN_OF_MED(LOC);
1642
1643   if (_status==MED_OPENED)
1644     {
1645
1646       int dtp3,itp3;
1647       med_2_3::med_float ttpp3;
1648       med_2_3::MEDmeshComputationStepInfo(_medIdt,_ptrMesh->_name.c_str(),1,&dtp3,&itp3,&ttpp3);
1649       int err = 0;
1650
1651 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64)
1652       med_2_3::med_int * tmp_MEDArrayNodeFamily = new med_2_3::med_int[_ptrMesh->getNumberOfNodes()];
1653       err=med_2_3::MEDmeshEntityFamilyNumberRd(_medIdt,_ptrMesh->_name.c_str(),dtp3,itp3,med_2_3::MED_NODE,MED_NONE,tmp_MEDArrayNodeFamily);
1654       int i;
1655       for ( i = 0; i < _ptrMesh->getNumberOfNodes(); i++ )
1656         MEDArrayNodeFamily[i] = tmp_MEDArrayNodeFamily[i];
1657       delete [] tmp_MEDArrayNodeFamily;
1658 #else
1659       err=med_2_3::MEDmeshEntityFamilyNumberRd(_medIdt,_ptrMesh->_name.c_str(),dtp3,itp3,med_2_3::MED_NODE,MED_NONE,MEDArrayNodeFamily);
1660 #endif
1661
1662       if ( err != MED_VALID)
1663         {
1664           std::fill(MEDArrayNodeFamily,MEDArrayNodeFamily+_ptrMesh->getNumberOfNodes(),0);
1665           //throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "There is no family for the |"<< _ptrMesh->getNumberOfNodes() << "| nodes in mesh |" << _ptrMesh->_name.c_str() << "|"));
1666         }
1667
1668       END_OF_MED(LOC);
1669       return MED_VALID;
1670     }
1671
1672   return MED_ERROR;
1673 }
1674
1675 int  MED_MESH_RDONLY_DRIVER::getCellsFamiliesNumber(int **MEDArrayFamily,
1676                                                     MED_EN::medEntityMesh entity)
1677 {
1678   const char * LOC = "MED_MESH_RDONLY_DRIVER::getCellsFamiliesNumber ";
1679
1680   BEGIN_OF_MED(LOC);
1681
1682   if (_status==MED_OPENED)
1683   {
1684     int dtp3,itp3;
1685     med_2_3::med_float ttpp3;
1686     med_2_3::MEDmeshComputationStepInfo(_medIdt,_ptrMesh->_name.c_str(),1,&dtp3,&itp3,&ttpp3);
1687     int i, err = 0;
1688     const MED_EN::medGeometryElement *types=_ptrMesh->getTypes(entity);
1689     for (i=0;i<_ptrMesh->getNumberOfTypes(entity);i++)
1690     {
1691 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64)
1692       int NumberOfCell=_ptrMesh->getNumberOfElements(entity,types[i]);
1693       med_2_3::med_int * tmp_MEDArrayFamily = new med_2_3::med_int[NumberOfCell];
1694       err=med_2_3::MEDmeshEntityFamilyNumberRd(_medIdt,_ptrMesh->_name.c_str(),dtp3,itp3,(med_2_3::med_entity_type) entity,(med_2_3::med_geometry_type)types[i],tmp_MEDArrayFamily);
1695       if (err != MED_VALID
1696           && !_ptrMesh->getIsAGrid()) // it's normal for a grid (PAL14113)
1697       {
1698         err=med_2_3::MEDmeshEntityFamilyNumberRd(_medIdt,_ptrMesh->_name.c_str(),dtp3,itp3,med_2_3::MED_CELL,(med_2_3::med_geometry_type)types[i],tmp_MEDArrayFamily);
1699         if (err != MED_VALID )
1700           {
1701             std::fill(tmp_MEDArrayFamily,tmp_MEDArrayFamily+NumberOfCell,0);
1702             //throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Family not found for entity "<<entity<<" and geometric type "<<types[i]));
1703           }
1704       }
1705       if (err == MED_VALID) {
1706         int ii;
1707         for ( ii = 0; ii < NumberOfCell; ii++ )
1708           MEDArrayFamily[i][ii] = tmp_MEDArrayFamily[ii];
1709       }
1710       delete [] tmp_MEDArrayFamily;
1711 #else
1712       err=med_2_3::MEDmeshEntityFamilyNumberRd(_medIdt,_ptrMesh->_name.c_str(),dtp3,itp3,(med_2_3::med_entity_type) entity,(med_2_3::med_geometry_type)types[i],MEDArrayFamily[i]);
1713
1714       if (err != MED_VALID
1715           && !_ptrMesh->getIsAGrid() ) // it's normal for a grid (PAL14113)
1716       {
1717         err=med_2_3::MEDmeshEntityFamilyNumberRd(_medIdt,_ptrMesh->_name.c_str(),dtp3,itp3,med_2_3::MED_CELL,(med_2_3::med_geometry_type)types[i],MEDArrayFamily[i]);
1718
1719         if (err != MED_VALID)
1720           {
1721             int NumberOfCell=_ptrMesh->getNumberOfElements(entity,types[i]);
1722             std::fill(MEDArrayFamily[i],MEDArrayFamily[i]+NumberOfCell,0);
1723             //throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Family not found for entity "<<entity<<" and geometric type "<<types[i]));
1724           }
1725       }
1726 #endif
1727     }
1728     return err ? MED_INVALID : MED_VALID;
1729   }
1730   return MED_ERROR;
1731 }
1732
1733 int MED_MESH_RDONLY_DRIVER::getDescendingConnectivity(CONNECTIVITY * Connectivity) 
1734 {
1735   if (_status==MED_OPENED)
1736     {
1737       MESSAGE_MED("MED_MESH_RDONLY_DRIVER::getDescendingConnectivity : "<<"call on the object " << Connectivity);
1738       MESSAGE_MED("MED_MESH_RDONLY_DRIVER::getDescendingConnectivity : "<<"Not yet implemented !");
1739     }
1740   return MED_ERROR;
1741 }
1742
1743 void MED_MESH_RDONLY_DRIVER::buildAllGroups(vector<GROUP*> & Groups, vector<FAMILY*> & Families) 
1744 {
1745   const char* LOC = "MED_MESH_RDONLY_DRIVER::buildAllGroups ";
1746   BEGIN_OF_MED(LOC);
1747
1748   int numberOfFamilies = Families.size() ;
1749   map< string,list<FAMILY*> > groupsNames ;
1750   for(int i=0; i<numberOfFamilies; i++) {
1751     FAMILY * myFamily = Families[i] ;
1752     int numberOfGroups_ = myFamily->getNumberOfGroups();
1753     for (int j=0; j<numberOfGroups_; j++) {
1754       groupsNames[myFamily->getGroupName(j+1)].push_back(myFamily);
1755     }
1756   }
1757   int numberOfGroups = groupsNames.size() ;
1758   SCRUTE_MED(numberOfGroups);
1759   Groups.resize(numberOfGroups);
1760   map< string,list<FAMILY*> >::const_iterator currentGroup ;
1761   int it = 0 ;
1762   for(currentGroup=groupsNames.begin();currentGroup!=groupsNames.end();currentGroup++) {
1763     GROUP * myGroup = new GROUP(healName((*currentGroup).first),(*currentGroup).second) ;
1764     _ptrMesh->removeReference();
1765     Groups[it]=myGroup;
1766     it++;
1767   }
1768
1769   END_OF_MED(LOC);
1770 }
1771
1772 void MED_MESH_RDONLY_DRIVER::updateFamily()
1773 {
1774   const char* LOC = "MED_MESH_RDONLY_DRIVER::updateFamily() ";
1775   BEGIN_OF_MED(LOC);
1776
1777   // we need to update family on constituent if we have constituent, but no 
1778   // descending connectivity, so, we must calculate all constituent and
1779   // numbering correctly family !
1780   if ( !_ptrMesh->getIsAGrid() )
1781   {
1782     MESH* mesh = (MESH*) _ptrMesh;
1783     mesh->_connectivity->updateFamily(_ptrMesh->_familyFace) ; // in 2d, do nothing
1784     mesh->_connectivity->updateFamily(_ptrMesh->_familyEdge) ; // in 3d, do nothing
1785   }
1786   END_OF_MED(LOC);
1787 }
1788
1789 /*--------------------- WRONLY PART -------------------------------*/
1790
1791 MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER():MED_MESH_DRIVER()
1792 {
1793   this->GENDRIVER::_accessMode = MED_EN::WRONLY;
1794 }
1795
1796 MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER(const string &         fileName,
1797                                                GMESH *                ptrMesh,
1798                                                MED_EN::med_mode_acces access):
1799   MED_MESH_DRIVER(fileName,ptrMesh,access)
1800 {
1801   MESSAGE_MED("MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
1802 }
1803
1804 MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER(const MED_MESH_WRONLY_DRIVER & driver):
1805   MED_MESH_DRIVER(driver)
1806 {
1807 }
1808
1809 MED_MESH_WRONLY_DRIVER::~MED_MESH_WRONLY_DRIVER()
1810 {
1811   //MESSAGE_MED("MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed");
1812 }
1813
1814 GENDRIVER * MED_MESH_WRONLY_DRIVER::copy(void) const
1815 {
1816   return new MED_MESH_WRONLY_DRIVER(*this);
1817 }
1818
1819 void MED_MESH_WRONLY_DRIVER::read (void)
1820 {
1821   throw MEDEXCEPTION("MED_MESH_WRONLY_DRIVER::read : Can't read with a WRONLY driver !");
1822 }
1823
1824 void MED_MESH_WRONLY_DRIVER::write(void) const
1825 {
1826
1827   if (_ptrMesh==NULL || _ptrMesh->getNumberOfNodes() < 1 )
1828     throw MEDEXCEPTION("Error trying to write an empty mesh");
1829
1830   const char * LOC = "void MED_MESH_WRONLY_DRIVER::write(void) const : ";
1831   BEGIN_OF_MED(LOC);
1832
1833   // we must first create mesh !!
1834   MESSAGE_MED(LOC << "MeshName : |" << _meshName << "| FileName : |"<<_fileName<<"| MedIdt : | "<< _medIdt << "|");
1835
1836   if (_status!=MED_OPENED)
1837     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "File "<<_fileName<<" is not open. Open it before write !"));
1838
1839
1840   string fieldName;
1841   if ( ( _meshName.empty() ) && ( _ptrMesh->_name.empty() )    )
1842     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)
1843                                  <<" neither <meshName> is set in driver nor in object MESH."));
1844
1845   // If _meshName is not set in driver, try to use _ptrmesh->_meshName
1846   if ( ( _meshName.empty() ) && ( !_ptrMesh->_name.empty() )    )
1847     _meshName = healName(_ptrMesh->_name );
1848
1849   if ( _meshName.size() > MED_NAME_SIZE )
1850     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)
1851                                  <<" <meshName> size in object driver MESH is > MED_NAME_SIZE ."));
1852
1853
1854   if (_ptrMesh->getIsAGrid())
1855   {
1856     if ( writeGRID() != MED_VALID )
1857       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeGRID()"  ));
1858   }
1859   else
1860   {
1861     if (writeCoordinates()!=MED_VALID)
1862       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeCoordinates()"  ));
1863
1864     if (writeConnectivities(MED_EN::MED_CELL)!=MED_VALID)
1865       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeConnectivities(MED_CELL)"  ));
1866     if (writeConnectivities(MED_EN::MED_FACE)!=MED_VALID)
1867       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeConnectivities(MED_FACE)"  ));
1868     if (writeConnectivities(MED_EN::MED_EDGE)!=MED_VALID)
1869       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeConnectivities(MED_EDGE)"  ));
1870   }
1871
1872   if (writeFamilyNumbers() !=MED_VALID)
1873     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilyNumbers()"  ));
1874
1875
1876   // well we must first write zero family :
1877   if (_status==MED_OPENED) {
1878     int err;
1879     // test if the family already exists (HDF trick waiting a MED evolution to be replaced)
1880     string dataGroupFam = "/ENS_MAA/"+_meshName+"/FAS/FAMILLE_ZERO/";
1881     MESSAGE_MED("|"<<dataGroupFam<<"|");
1882     err =med_2_3::_MEDdatagroupOuvrir(_medIdt,const_cast <char *> (dataGroupFam.c_str()) );
1883     if ( err < MED_VALID ) {
1884       SCRUTE_MED(err);
1885
1886       char familyName[MED_NAME_SIZE+1];
1887       strcpy(familyName,"FAMILLE_ZERO");
1888       err = med_2_3::MEDfamilyCr(_medIdt,_meshName.c_str(),familyName,0,0,0);
1889
1890       SCRUTE_MED(familyName);
1891
1892       if ( err != MED_VALID)
1893         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't create family |FAMILLE_ZERO| with identifier |0| groups names || and  attributes descriptions ||"));
1894     }
1895     else
1896       med_2_3::_MEDdatagroupFermer(_medIdt);
1897
1898   }
1899
1900   MESSAGE_MED(LOC<<"writeFamilies(_ptrMesh->_familyNode)");
1901   if (writeFamilies(_ptrMesh->_familyNode) !=MED_VALID)
1902     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyNode)"  ));
1903
1904   MESSAGE_MED(LOC<<"writeFamilies(_ptrMesh->_familyCell)");
1905   if (writeFamilies(_ptrMesh->_familyCell) !=MED_VALID)
1906     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyCell)"  ));
1907
1908   MESSAGE_MED(LOC<<"writeFamilies(_ptrMesh->_familyFace)");
1909   if (writeFamilies(_ptrMesh->_familyFace) !=MED_VALID)
1910     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyFace)"  ));
1911
1912   MESSAGE_MED(LOC<<"writeFamilies(_ptrMesh->_familyEdge)");
1913   if (writeFamilies(_ptrMesh->_familyEdge) !=MED_VALID)
1914     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyEdge)"  ));
1915
1916   END_OF_MED(LOC);
1917 }
1918
1919 //=======================================================================
1920 //function : writeGRID
1921 //purpose  :
1922 //=======================================================================
1923
1924 int MED_MESH_WRONLY_DRIVER::writeGRID() const
1925 {
1926   const char * LOC = "MED_MESH_WRONLY_DRIVER::writeGRID() : ";
1927   BEGIN_OF_MED(LOC);
1928
1929   if (_status!=MED_OPENED)
1930   {
1931     MESSAGE_MED (LOC<<" Not open !!!");
1932     return MED_ERROR;
1933   }
1934   GRID * ptrGrid = (GRID*) _ptrMesh;
1935
1936   med_2_3::med_err err = MED_ERROR;
1937   med_2_3::med_axis_type rep;
1938   string tmp_name(_ptrMesh->_spaceDimension*MED_SNAME_SIZE,' ');
1939   string tmp_unit(_ptrMesh->_spaceDimension*MED_SNAME_SIZE,' ');
1940
1941   // Test if the mesh <_meshName> already exists
1942   // If it doesn't exists create it
1943   // If it already exists verify if its space and mesh dimensions are the same
1944   // as <_ptrMesh->_spaceDimension>, <_ptrMesh->getMeshDimension()> respectively
1945   // rem : <_meshName> is the driver meshName not <ptrMesh->_meshName>
1946
1947   med_2_3::med_int dtpp3,itpp3;
1948   med_2_3::med_float ttpp3;
1949   err=med_2_3::MEDmeshComputationStepInfo(_medIdt,_meshName.c_str(),1,&dtpp3,&itpp3,&ttpp3);
1950
1951   int spaceDimension=-1;
1952   int meshDimension=-1;
1953   if(!err)
1954     {
1955       med_2_3::med_mesh_type ttmp3;
1956       char commentp3[MED_COMMENT_SIZE+1];
1957       char dtunittp3[MED_LNAME_SIZE+1];
1958       med_2_3::med_sorting_type sttp3;
1959       int nstep;
1960       med_2_3::med_axis_type axtypp3;
1961       int naxis=std::max( 3, med_2_3::MEDmeshnAxisByName(_medIdt,_meshName.c_str()));
1962       char *t1pp3=new char[naxis*MED_SNAME_SIZE+1];
1963       char *t2pp3=new char[naxis*MED_SNAME_SIZE+1];
1964       med_2_3::MEDmeshInfoByName(_medIdt,_meshName.c_str(),&spaceDimension,&meshDimension,&ttmp3,commentp3,dtunittp3,&sttp3,&nstep,&axtypp3,t1pp3,t2pp3);
1965       delete [] t1pp3;
1966       delete [] t2pp3;
1967     }
1968   // Recompose the <_spaceDimension> strings in 1 string
1969   int lengthString;
1970   string valueString;
1971   for (int i=0;i<_ptrMesh->_spaceDimension;i++) {
1972     SCRUTE_MED(i);
1973     valueString = ptrGrid->_coordinate->_coordinateName[i];
1974     lengthString = (MED_SNAME_SIZE<valueString.size())?MED_SNAME_SIZE:valueString.size();
1975     tmp_name.replace(i*MED_SNAME_SIZE,i*MED_SNAME_SIZE+lengthString,valueString,0,lengthString);
1976     valueString = ptrGrid->_coordinate->_coordinateUnit[i];
1977     lengthString = (MED_SNAME_SIZE<valueString.size())?MED_SNAME_SIZE:valueString.size();
1978     tmp_unit.replace(i*MED_SNAME_SIZE,i*MED_SNAME_SIZE+lengthString,valueString,0,lengthString);
1979   }
1980
1981   if (err) // create a mesh in the file
1982     {
1983       // Pourquoi le stocker sous forme de chaîne ?
1984       const string & coordinateSystem = ptrGrid->_coordinate->_coordinateSystem;
1985       if      (coordinateSystem  == "CARTESIAN")
1986         rep = med_2_3::MED_CARTESIAN;
1987       else if ( coordinateSystem == "CYLINDRICAL")
1988         rep = med_2_3::MED_CYLINDRICAL;
1989       else if ( coordinateSystem == "SPHERICAL" )
1990         rep = med_2_3::MED_SPHERICAL;
1991       else
1992         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Grid |" << _meshName.c_str() <<
1993                                      "| doesn't have a valid coordinate system : |"
1994                                      << ptrGrid->_coordinate->_coordinateSystem
1995                                      << "|" ));
1996
1997       _ptrMesh->_description.resize(MED_COMMENT_SIZE+1,'\0');
1998       char dtunitp3[MED_LNAME_SIZE+1];
1999       std::fill(dtunitp3,dtunitp3+MED_LNAME_SIZE+1,'\0');
2000
2001       err = med_2_3::MEDmeshCr(_medIdt,_meshName.c_str(),
2002                                _ptrMesh->getSpaceDimension(),
2003                                _ptrMesh->getMeshDimension(),
2004                                med_2_3::MED_STRUCTURED_MESH,
2005                                _ptrMesh->_description.c_str(),
2006                                dtunitp3,med_2_3::MED_SORT_DTIT,
2007                                rep,
2008                                const_cast <char *> (tmp_name.c_str()),
2009                                const_cast <char *> (tmp_unit.c_str()));
2010
2011       if (err != MED_VALID)
2012         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Unable to create Grid"));
2013       else
2014         MESSAGE_MED(LOC<<"Grid "<<_meshName<<" created in file "<<_fileName<<" !");
2015
2016       err = med_2_3::MEDmeshGridTypeWr(_medIdt,_meshName.c_str(),
2017                                        (med_2_3::med_grid_type)ptrGrid->getGridType());
2018       if (err != MED_VALID)
2019         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Error in MEDmeshGridTypeWr()"));
2020
2021       meshDimension =  _ptrMesh->getMeshDimension();
2022     }
2023   else if ((spaceDimension != _ptrMesh->_spaceDimension)  &&
2024            (meshDimension != _ptrMesh->getMeshDimension()))
2025     {
2026       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Grid |" << _meshName.c_str() <<
2027                                    "| already exists in file |" << _fileName <<
2028                                    "| with space dimension |" << spaceDimension <<
2029                                    "| and mesh dimension |" << meshDimension <<
2030                                    "| but the space dimension and the mesh dimension of "
2031                                    "the mesh we want to write are respectively |"
2032                                    << _ptrMesh->_spaceDimension <<"|" <<
2033                                    _ptrMesh->getMeshDimension() <<"|" ));
2034     }
2035
2036   MED_EN::med_grid_type gridType = ptrGrid->getGridType();
2037
2038   if (err != MED_VALID)
2039     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Unable to write the type of the Grid"));
2040
2041
2042   med_2_3::med_int ArrayLen[] = { (med_2_3::med_int) ptrGrid->_iArrayLength,
2043                                   (med_2_3::med_int) ptrGrid->_jArrayLength,
2044                                   (med_2_3::med_int) ptrGrid->_kArrayLength  };
2045
2046   // Write node coordinates for MED_BODY_FITTED grid
2047   if (gridType == MED_EN::MED_BODY_FITTED)
2048     {
2049       // Write Coordinates and families
2050
2051       err = med_2_3::MEDmeshNodeCoordinateWr(_medIdt,_meshName.c_str(),
2052                                              MED_NO_DT,MED_NO_IT,MED_NO_DT,
2053                                              med_2_3::MED_FULL_INTERLACE,
2054                                              ptrGrid->getNumberOfNodes(),
2055                                              ptrGrid->_coordinate->_coordinate.get(MED_EN::MED_FULL_INTERLACE));
2056
2057       if (err != MED_VALID)
2058         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write coordinates of the grid |" << _meshName.c_str() << "| in file |" << _fileName
2059                                      << "| with dimension |"  << _ptrMesh->_spaceDimension <<"| and"
2060                                      << " with units names |"  << tmp_name
2061                                      << "| and units |"       << tmp_unit
2062                                      << " |"));
2063
2064       med_2_3::med_int* structure = new med_2_3::med_int [meshDimension];
2065
2066       for (int idim = 0; idim < meshDimension; ++idim)
2067         structure[idim] = ArrayLen [idim];
2068
2069
2070       err = med_2_3::MEDmeshGridStructWr(_medIdt,_meshName.c_str(),
2071                                          MED_NO_DT,MED_NO_IT,MED_NO_DT,
2072                                          structure);
2073
2074       if (err != MED_VALID)
2075         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"error in writing the structure of the grid |" << _meshName.c_str()));
2076
2077       delete [] structure;
2078     }
2079   else if ((gridType == MED_EN::MED_CARTESIAN) ||
2080            (gridType == MED_EN::MED_POLAR))
2081     {
2082       // Write Arrays of Cartesian or Polar Grid
2083
2084       double * Array[] = { ptrGrid->_iArray,
2085                            ptrGrid->_jArray,
2086                            ptrGrid->_kArray };
2087
2088       for (int idim = 0; idim < _ptrMesh->getMeshDimension(); ++idim)
2089         {
2090           string str_name = string (tmp_name,idim*MED_SNAME_SIZE,
2091                                     MED_SNAME_SIZE);
2092           string str_unit = string (tmp_unit,idim*MED_SNAME_SIZE,
2093                                     MED_SNAME_SIZE);
2094
2095           err = med_2_3::MEDmeshGridIndexCoordinateWr(_medIdt,_meshName.c_str(),
2096                                                       MED_NO_DT,MED_NO_IT,MED_NO_DT,
2097                                                       idim+1,
2098                                                       ArrayLen[idim],
2099                                                       Array[idim]);
2100
2101           if (err != MED_VALID)
2102             throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<
2103                                          "Can't write grid coordinates for " <<
2104                                          idim << "-th dimention"));
2105         }
2106   } // end Write  Cartesian or Polar Grid
2107
2108   END_OF_MED(LOC);
2109   return MED_VALID;
2110 }
2111
2112 //=======================================================================
2113 //function : writeCoordinates
2114 //purpose  :
2115 //=======================================================================
2116
2117 int MED_MESH_WRONLY_DRIVER::writeCoordinates() const {
2118
2119   const char * LOC = "int MED_MESH_WRONLY_DRIVER::writeCoordinates() const : ";
2120   BEGIN_OF_MED(LOC);
2121
2122   MESH * ptrMesh = (MESH*) _ptrMesh;
2123
2124   med_2_3::med_err err = MED_ERROR;
2125   med_2_3::med_axis_type rep;
2126   string tmp_name(ptrMesh->_spaceDimension*MED_SNAME_SIZE+1,' ');
2127   string tmp_unit(ptrMesh->_spaceDimension*MED_SNAME_SIZE+1,' ');
2128
2129   // Recompose the <_spaceDimension> strings in 1 string
2130   int lengthString;
2131   string valueString;
2132   for (int i=0;i<ptrMesh->_spaceDimension;i++) {
2133     valueString = ptrMesh->_coordinate->_coordinateName[i];
2134     lengthString = (MED_SNAME_SIZE<valueString.size())?MED_SNAME_SIZE:valueString.size();
2135     tmp_name.replace(i*MED_SNAME_SIZE,i*MED_SNAME_SIZE+lengthString,valueString,0,lengthString);
2136     valueString = ptrMesh->_coordinate->_coordinateUnit[i];
2137     lengthString = (MED_SNAME_SIZE<valueString.size())?MED_SNAME_SIZE:valueString.size();
2138     tmp_unit.replace(i*MED_SNAME_SIZE,i*MED_SNAME_SIZE+lengthString,valueString,0,lengthString);
2139   }
2140   // Pourquoi le stocker sous forme de chaîne ?
2141   const string & coordinateSystem = ptrMesh->_coordinate->_coordinateSystem;
2142   if      (coordinateSystem  == "CARTESIAN")
2143     rep = med_2_3::MED_CARTESIAN;
2144   else if ( coordinateSystem == "CYLINDRICAL")
2145     rep = med_2_3::MED_CYLINDRICAL;
2146   else if ( coordinateSystem == "SPHERICAL" )
2147     rep = med_2_3::MED_SPHERICAL;
2148   else
2149     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Mesh |" << _meshName.c_str() << "| doesn't have a valid coordinate system : |"
2150                                  << ptrMesh->_coordinate->_coordinateSystem
2151                                  << "|" ));
2152   // Test if the mesh <_meshName> already exists
2153   // If it doesn't exists create it
2154   // If it already exists verify if its space and mesh dimensions are the same
2155   // as <ptrMesh->_spaceDimension>, <ptrMesh->getMeshDimension()> respectively
2156   // rem : <_meshName> is the driver meshName not <ptrMesh->_meshName>
2157
2158   med_2_3::med_int dtpp3,itpp3;
2159   med_2_3::med_float ttpp3;
2160   err=med_2_3::MEDmeshComputationStepInfo(_medIdt,_meshName.c_str(),1,&dtpp3,&itpp3,&ttpp3);
2161   int spaceDimension=-1;
2162   int meshDimension=-1;
2163   if(!err)
2164     {
2165       med_2_3::med_mesh_type ttmp3;
2166       char commentp3[MED_COMMENT_SIZE+1];
2167       char dtunittp3[MED_LNAME_SIZE+1];
2168       med_2_3::med_sorting_type sttp3;
2169       int nstep;
2170       med_2_3::med_axis_type axtypp3;
2171       int naxis=med_2_3::MEDmeshnAxisByName(_medIdt,_meshName.c_str());
2172       if ( naxis > 0 )
2173         {
2174           char *t1pp3=new char[naxis*MED_SNAME_SIZE+1];
2175           char *t2pp3=new char[naxis*MED_SNAME_SIZE+1];
2176           med_2_3::MEDmeshInfoByName(_medIdt,_meshName.c_str(),&spaceDimension,&meshDimension,&ttmp3,commentp3,dtunittp3,&sttp3,&nstep,&axtypp3,t1pp3,t2pp3);
2177           delete [] t1pp3;
2178           delete [] t2pp3;
2179         }
2180       else
2181         {
2182           err = MED_INVALID;
2183         }
2184     }
2185   SCRUTE_MED(spaceDimension);
2186   SCRUTE_MED(meshDimension);
2187   SCRUTE_MED(ptrMesh->_spaceDimension);
2188   SCRUTE_MED(ptrMesh->getMeshDimension());
2189
2190   if (err)
2191     {
2192       _ptrMesh->_description.resize(MED_COMMENT_SIZE+1,'\0');
2193       char dtunitp3[MED_LNAME_SIZE+1];
2194       std::fill(dtunitp3,dtunitp3+MED_LNAME_SIZE+1,'\0');
2195
2196       err = med_2_3::MEDmeshCr(_medIdt,_meshName.c_str(),
2197                                _ptrMesh->getSpaceDimension(),
2198                                _ptrMesh->getMeshDimension(),
2199                                med_2_3::MED_UNSTRUCTURED_MESH,
2200                                _ptrMesh->_description.c_str(),
2201                                dtunitp3,
2202                                med_2_3::MED_SORT_DTIT,
2203                                rep,
2204                                const_cast <char *> (tmp_name.c_str()),
2205                                const_cast <char *> (tmp_unit.c_str()));
2206
2207       if (err < MED_VALID)
2208         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Unable to create Mesh : |" << _meshName << "|"));
2209       else
2210         MESSAGE_MED(LOC<<"Mesh "<<_meshName<<" created in file "<<_fileName<<" !");
2211     }
2212   else if ((spaceDimension != ptrMesh->_spaceDimension)  &&
2213            (meshDimension != ptrMesh->getMeshDimension()))
2214     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Mesh |" << _meshName.c_str() <<
2215                                  "| already exists in file |" << _fileName <<
2216                                  "| with space dimension |" << spaceDimension <<
2217                                  "| and mesh dimension |" << meshDimension <<
2218                                  "| but the space dimension and the mesh dimension of the mesh we want to write are respectively |"
2219                                  << ptrMesh->_spaceDimension <<"|" <<
2220                                  ptrMesh->getMeshDimension() << "|"));
2221   
2222   err=med_2_3::MEDmeshNodeCoordinateWr(_medIdt,_meshName.c_str(),MED_NO_DT,MED_NO_IT,MED_NO_DT,med_2_3::MED_FULL_INTERLACE,ptrMesh->getNumberOfNodes(),
2223                                        const_cast <double *> ( ptrMesh->_coordinate->_coordinate.get(MED_EN::MED_FULL_INTERLACE)));
2224
2225   if (err<0)
2226     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write coordinates of mesh |" << _meshName.c_str() << "| in file |" << _fileName
2227                                  << "| with dimension |"  << ptrMesh->_spaceDimension <<"| and"
2228                                  << " with units names |"  << tmp_name
2229                                  << "| and units |"       << tmp_unit
2230                                  << " |"));
2231
2232
2233        //////////////////////////////////////////////////////////////////////////////////////
2234        ///  Modification pour prise en compte de la numérotation optionnelle des noeuds   ///
2235        //////////////////////////////////////////////////////////////////////////////////////
2236        ///
2237        /// Ecrit les numéros optionnels des noeuds
2238        /// Le traitement est identique à la version originelle s'il n'y a pas de numérotation optionnelle
2239
2240
2241       if (ptrMesh->_arePresentOptionnalNodesNumbers==1) {
2242
2243 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64)
2244         const int * NodesNumbers = ptrMesh->_coordinate->getNodesNumbers();
2245         med_2_3::med_int * tmp_NodesNumbers = new med_2_3::med_int[ptrMesh->getNumberOfNodes()];
2246         int ii;
2247         for ( ii = 0; ii < ptrMesh->getNumberOfNodes(); ii++ )
2248            tmp_NodesNumbers[ii] = NodesNumbers[ii];
2249         err=med_2_3::MEDmeshEntityNumberWr(_medIdt,_meshName.c_str(),MED_NO_DT,MED_NO_IT,med_2_3::MED_NODE,MED_NONE,ptrMesh->getNumberOfNodes(),
2250                                            tmp_NodesNumbers);
2251         delete [] tmp_NodesNumbers;
2252 #else
2253         err=med_2_3::MEDmeshEntityNumberWr(_medIdt,_meshName.c_str(),MED_NO_DT,MED_NO_IT,med_2_3::MED_NODE,MED_NONE,ptrMesh->getNumberOfNodes(),
2254                                            const_cast<med_int *>(ptrMesh->_coordinate->getNodesNumbers()));
2255 #endif
2256
2257         if (err != MED_VALID)
2258           throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write optionnal numbers of mesh |" <<
2259                                        _meshName.c_str() << "| in file |" <<
2260                                        _fileName  << " |"));
2261       }
2262       //////////////////////////////////////////////////////////////////////////////////////
2263
2264   END_OF_MED(LOC);
2265
2266   return MED_VALID;
2267 }
2268
2269
2270
2271
2272 int MED_MESH_WRONLY_DRIVER::writeConnectivities(medEntityMesh entity) const
2273 {
2274   const char * LOC="int MED_MESH_WRONLY_DRIVER::writeConnectivities() const : ";
2275   BEGIN_OF_MED(LOC);
2276
2277   med_2_3::med_err err;
2278
2279   MESH * ptrMesh = (MESH*) _ptrMesh;
2280
2281   if ( ptrMesh->_connectivity == (CONNECTIVITY *) NULL )
2282     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The connectivity is not defined in the MESH object "));
2283
2284
2285   if ( ptrMesh->existConnectivity(MED_NODAL,entity) )
2286     {
2287       int numberOfTypes = ptrMesh->getNumberOfTypes(entity);
2288       const medGeometryElement * types = ptrMesh->getTypes(entity);
2289       const int * index = ptrMesh->getConnectivityIndex(MED_NODAL, entity);
2290
2291       for (int i=0; i<numberOfTypes; i++)
2292         {
2293           int numberOfElements = ptrMesh->getNumberOfElements(entity,types[i]);
2294           const int * connectivity = ptrMesh->getConnectivity(MED_NODAL, entity, types[i]);
2295           int size = ptrMesh->getConnectivityLength(MED_NODAL, entity, types[i]);
2296
2297           switch ( types[i] )
2298             {
2299             case MED_EN::MED_POLYGON:
2300               {
2301                 int nbStdCells = ptrMesh->getGlobalNumberingIndex(entity)[i]-1;
2302                 vector< med_2_3::med_int > connectivityArray( connectivity, connectivity + size );
2303                 vector< med_2_3::med_int > tmp_Index( numberOfElements+1 );
2304                 for ( unsigned j = 0; j < tmp_Index.size(); ++ j )
2305                   tmp_Index[j] = index[ nbStdCells + j ] - index[ nbStdCells ] + 1;
2306                 err=med_2_3::MEDmeshPolygonWr(_medIdt,_meshName.c_str(),
2307                                               MED_NO_DT,MED_NO_IT,MED_NO_DT,
2308                                               med_2_3::MED_CELL,
2309                                               med_2_3::MED_NODAL,
2310                                               numberOfElements+1,
2311                                               &tmp_Index[0],
2312                                               &connectivityArray[0]);
2313
2314                 if (err<0)
2315                   throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write polygons nodal connectivities of mesh |"
2316                                                <<  _meshName.c_str() << "| in file |" << _fileName
2317                                                << "| with dimension |"  << ptrMesh->_spaceDimension <<"| and"
2318                                                ));
2319                 break;
2320               }
2321             case MED_EN::MED_POLYHEDRA:
2322               {
2323                 vector< med_2_3::med_int > PolyhedronIndex, PolyhedronFacesIndex, PolyhedronConnectivity;
2324                 PolyhedronIndex.push_back(1);
2325                 PolyhedronFacesIndex.push_back(1);
2326                 connectivity = ptrMesh->getConnectivity(MED_NODAL, entity, MED_ALL_ELEMENTS);
2327                 int nbStdCells = ptrMesh->getGlobalNumberingIndex(entity)[i]-1;
2328                 for ( int j = nbStdCells; j < nbStdCells+numberOfElements; ++j )
2329                   {
2330                     for ( int k = index[j]; k < index[j+1]; ++k )
2331                       if ( connectivity[k-1] == -1 )
2332                         PolyhedronFacesIndex.push_back( PolyhedronConnectivity.size()+1 );
2333                       else
2334                         PolyhedronConnectivity.push_back( connectivity[k-1] );
2335                     PolyhedronIndex.push_back( PolyhedronFacesIndex.size()+1 );
2336                     PolyhedronFacesIndex.push_back( PolyhedronConnectivity.size()+1 );
2337                   }
2338                 err=med_2_3::MEDmeshPolyhedronWr(_medIdt,_meshName.c_str(),
2339                                                  MED_NO_DT,MED_NO_IT,MED_NO_DT,
2340                                                  med_2_3::MED_CELL,
2341                                                  med_2_3::MED_NODAL,
2342                                                  PolyhedronIndex.size(),
2343                                                  &PolyhedronIndex[0],
2344                                                  PolyhedronFacesIndex.size(),
2345                                                  &PolyhedronFacesIndex[0],
2346                                                  &PolyhedronConnectivity[0]);
2347                 if (err<0)
2348                   throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write polyhedron nodal connectivities of mesh |"
2349                                                << _meshName.c_str() << "| in file |" << _fileName
2350                                                << "| with dimension |"  << ptrMesh->_spaceDimension <<"| and"
2351                                                ));
2352                 break;
2353               }
2354             default:
2355
2356               vector< med_2_3::med_int > connectivityArray( connectivity, connectivity + size );
2357               err=med_2_3::MEDmeshElementConnectivityWr(_medIdt,_meshName.c_str(),MED_NO_DT,MED_NO_IT,MED_NO_DT,med_2_3::MED_CELL,(med_2_3::med_geometry_type)types[i],
2358                                                         med_2_3::MED_NODAL,med_2_3::MED_FULL_INTERLACE,numberOfElements,&connectivityArray[0]);
2359
2360               if (err<0) // ETENDRE LES EXPLICATIONS
2361                 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write connectivities of mesh |"
2362                                              << _meshName.c_str() << "| in file |" << _fileName
2363                                              << "| with dimension |"  << ptrMesh->_spaceDimension <<"| and"));
2364             }
2365         }
2366     }
2367
2368
2369   // Descending connectivity for classic geometric types
2370   if ( ptrMesh->existConnectivity(MED_DESCENDING,entity) )
2371     {
2372       int numberOfTypes                = ptrMesh->getNumberOfTypes (entity);
2373       const medGeometryElement * types = ptrMesh->getTypes         (entity);
2374
2375       for (int i=0; i<numberOfTypes; i++)
2376         {
2377           int    numberOfElements = ptrMesh->getNumberOfElements (entity,types[i]);
2378           const int * connectivity = ptrMesh->getConnectivity(MED_DESCENDING, entity, types[i]);
2379
2380 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64)
2381           int lgth = ptrMesh->getConnectivityLength(MED_DESCENDING, entity, types[i]);
2382           vector< med_2_3::med_int > tmp_Connectivity( connectivity, connectivity + lgth );
2383           err=med_2_3::MEDmeshElementConnectivityWr(_medIdt,_meshName.c_str(),
2384                                                     MED_NO_DT,MED_NO_IT,MED_NO_DT,
2385                                                     med_2_3::MED_CELL,
2386                                                     (med_2_3::med_geometry_type)types[i],
2387                                                     med_2_3::MED_DESCENDING,
2388                                                     med_2_3::MED_FULL_INTERLACE,
2389                                                     numberOfElements,
2390                                                     &tmp_Connectivity[0]);
2391 #else
2392           err=med_2_3::MEDmeshElementConnectivityWr(_medIdt,_meshName.c_str(),
2393                                                     MED_NO_DT,MED_NO_IT,MED_NO_DT,
2394                                                     med_2_3::MED_CELL,
2395                                                     (med_2_3::med_geometry_type)types[i],
2396                                                     med_2_3::MED_DESCENDING,
2397                                                     med_2_3::MED_FULL_INTERLACE,
2398                                                     numberOfElements,
2399                                                     const_cast<int *>(connectivity));
2400 #endif
2401
2402           if (err<0) // ETENDRE LES EXPLICATIONS
2403             throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write connectivities of mesh |"
2404                                          << _meshName.c_str() << "| in file |" << _fileName
2405                                          << "| with dimension |"  << ptrMesh->_spaceDimension <<"| and"
2406                                          ));
2407
2408         }
2409     }
2410
2411   END_OF_MED(LOC);
2412   return MED_VALID;
2413 }
2414
2415 /*!creates a vector of families from a vector of groups
2416  *
2417  * \param myGroups input : vector of groups
2418  * \param myFamilies output vector of families
2419  *
2420  * Routine is meant to be called to reconstruct families from existing groups
2421  * typically for writing meshes created by MEDMEM::MESHING containing overlapping groups
2422  *
2423  * if the groups do not overlap, the vector of families will have the same size
2424  * as the vector of groups
2425  * otherwise, the size of the family vector will be larger
2426 */
2427
2428 void MED_MESH_WRONLY_DRIVER::groupFamilyConverter(const vector <GROUP*>& myGroups, vector <FAMILY*>& myFamilies ) const
2429 {
2430
2431   const char* LOC = "MED_MESH_WRONLY_DRIVER::groupFamilyConverter";
2432   BEGIN_OF_MED(LOC);
2433   if (myGroups.empty()) return;
2434
2435 //      if (!myFamilies.empty())
2436 //      throw MEDEXCEPTION(LOCALIZED("Family vector must be empty on call "
2437 //      << "to groupFamilyConverter"));
2438 //
2439  //mapping elements to all the groups containing it
2440   std::multimap <int,int> elem2groups;
2441   for (int igroup=0; igroup< (int)myGroups.size(); igroup++)
2442   {
2443     const int*Number = myGroups[igroup]->getNumber(MED_ALL_ELEMENTS);
2444     for (int ielem = 0; ielem< myGroups[igroup]->getNumberOfElements(MED_ALL_ELEMENTS); ielem++)
2445     {
2446       elem2groups.insert(make_pair(Number[ielem], igroup));
2447     }
2448   }
2449
2450   //creating a set of signatures for the groups intersections
2451   std::multimap<vector<int>,int> signatures;
2452
2453   typedef multimap<int,int>::iterator MI;
2454   MI iter=elem2groups.begin();
2455
2456   while (iter!=elem2groups.end())
2457   {
2458     vector<int> sign (1, iter -> second );
2459     int key = iter -> first;
2460     iter ++;
2461     while (iter!=elem2groups.end()&&iter-> first == key)
2462     {
2463       sign.push_back(iter -> second);
2464       iter++;
2465     }
2466     signatures.insert(make_pair(sign,key));
2467   }
2468
2469   elem2groups.clear();
2470
2471   //creating the families from the signatures mapping
2472   //each signature will correspond to a new family
2473   std::multimap<vector<int>,int>::const_iterator iter_signatures = signatures.begin();
2474
2475   //retrieving the entity type (all the groups have the same)
2476   // node families are numbered above 0
2477   // cell families are numbered from  -1 to -MAX_NB_GROUPS
2478   // face falimies are numbered from -MAX_NB_GROUPS-1 to -2*MAX_NB_GROUPS
2479   // edge families are numbered from -2*MAX_NB_GROUPS to -3*MAX_NB_GROUPS
2480   // MAX_NB_GROUPS is defined in MEDMEM_define.hxx
2481
2482   medEntityMesh entity = myGroups[0]->getEntity();
2483   MESH* mesh=(MESH*)myGroups[0]->getMesh();
2484
2485   int ifamily;
2486   switch (entity)
2487   {
2488   case MED_NODE:
2489     ifamily=1;
2490     break;
2491   case MED_CELL:
2492     ifamily=-MAX_NB_GROUP;
2493     break;
2494   case MED_FACE:
2495     ifamily=-2*MAX_NB_GROUP;
2496     break;
2497   case MED_EDGE:
2498     ifamily=-3*MAX_NB_GROUP;
2499     break;
2500   }
2501
2502   //browsing signatures to build all the families
2503   //each signature corresponds to a new family
2504
2505   while (iter_signatures!= signatures.end())
2506   {
2507     const vector<int>& key= iter_signatures->first;
2508     int size = signatures.count(key);
2509
2510     list<int> numbers;
2511
2512     for (int i=0; i< size; i++)
2513     {
2514       numbers.push_back(iter_signatures->second);
2515       iter_signatures++;
2516     }
2517
2518     //TODO : see if build SupportOnElementFromElementList could not be built from another container
2519
2520     // for nodes, the family is built directly from the node list
2521     // for elements, it is built from the buildSupportOnElementsFromElementList
2522     //               which allocates a support
2523     FAMILY* myFamily;
2524     if (entity!=MED_NODE)
2525     {
2526       SUPPORT* support;
2527       support=mesh->buildSupportOnElementsFromElementList(numbers, entity);
2528       myFamily=new FAMILY(*support);
2529       support->removeReference();
2530     }
2531     else
2532     {
2533       myFamily= new FAMILY();
2534       myFamily->setMesh(mesh);
2535       myFamily->fillFromNodeList(numbers);
2536     }
2537
2538
2539     // the identifier and the groups are set
2540     myFamily->setIdentifier(ifamily);
2541     myFamily->setNumberOfGroups(key.size());
2542     char family_name[MED_NAME_SIZE];
2543
2544     //if the family has one group to which only one family
2545     //is associated, the name of the family underlying the group
2546     //is given back to the family
2547     if (key.size()==1 && myGroups[key[0]]->getNumberOfFamilies()==0)
2548     {
2549       vector<FAMILY*> families;
2550       families.push_back(myFamily);
2551       myGroups[key[0]]->setFamilies(families);
2552       //it is necessary to use strncpy because group and family
2553       //have different name sizes
2554       strncpy(family_name,myGroups[key[0]]->getName().c_str(),MED_NAME_SIZE);
2555       family_name[MED_NAME_SIZE-1]='\0';
2556     }
2557     else
2558       sprintf(family_name,"family%d",ifamily);
2559
2560     myFamily->setName( healName( family_name ));
2561
2562     string* groupnames=new string[key.size()];
2563
2564     for (int igroup=0; igroup<(int)key.size(); igroup++)
2565     {
2566       groupnames[igroup]=myGroups[key[igroup]]->getName();
2567     }
2568
2569     myFamily->setGroupsNames(groupnames,true);
2570     if(myFamily->getMesh()==_ptrMesh)
2571       _ptrMesh->removeReference();
2572     myFamilies.push_back(myFamily);
2573     ifamily++;
2574   }
2575
2576   //adding empty families corresponding to empty groups
2577   for (size_t i=0; i<myGroups.size(); i++)
2578   {
2579     if (myGroups[i]->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)==0)
2580     {
2581       FAMILY* myFamily=new FAMILY(*(myGroups[i]));
2582       char family_name[MED_NAME_SIZE];
2583       //it is necessary to use strncpy because group and family
2584       //have different name sizes
2585       strncpy(family_name,myGroups[i]->getName().c_str(),MED_NAME_SIZE);
2586       family_name[MED_NAME_SIZE-1]='\0';
2587       myFamily->setName( healName( family_name ));
2588       myFamily->setIdentifier(ifamily);
2589       ifamily++;
2590       vector<string> groupnames;
2591       groupnames.push_back(myGroups[i]->getName());
2592       myFamily->setNumberOfGroups(1);
2593       myFamily->setGroupsNames(&groupnames[0]);
2594       if(myFamily->getMesh()==_ptrMesh)
2595         _ptrMesh->removeReference();
2596       myFamilies.push_back(myFamily);
2597     }
2598   }
2599   END_OF_MED(LOC);
2600 }
2601
2602 int MED_MESH_WRONLY_DRIVER::writeFamilyNumbers() const {
2603
2604   const char * LOC="int MED_MESH_WRONLY_DRIVER::writeFamilyNumbers() const : ";
2605   BEGIN_OF_MED(LOC);
2606
2607   med_2_3::med_err err;
2608
2609   // SOLUTION TEMPORAIRE CAR _ptrMesh->_MEDArrayNodeFamily DOIT ETRE ENLEVER DE LA CLASSE MESH
2610
2611   { // Node related block
2612
2613     // We build the array from the families list objects :
2614     int NumberOfNodes = _ptrMesh->getNumberOfNodes();
2615     med_2_3::med_int * MEDArrayNodeFamily = new med_2_3::med_int[NumberOfNodes];
2616     // family 0 by default
2617     for (int i=0; i<NumberOfNodes; i++)
2618       MEDArrayNodeFamily[i]=0;
2619     vector<FAMILY*> * myFamilies = &_ptrMesh->_familyNode;
2620     int NumberOfNodesFamilies = myFamilies->size();
2621     if (0 == NumberOfNodesFamilies) {
2622       vector<GROUP*> myGroups = _ptrMesh->getGroups(MED_NODE);
2623
2624       groupFamilyConverter(myGroups,*myFamilies);
2625
2626       NumberOfNodesFamilies=myFamilies->size();
2627     }
2628     for (int i=0; i<NumberOfNodesFamilies; i++) {
2629       int FamilyIdentifier = (*myFamilies)[i]->getIdentifier();
2630       int TotalNumber = (*myFamilies)[i]->getNumberOfElements(MED_ALL_ELEMENTS);
2631       const int * Number = (*myFamilies)[i]->getNumber(MED_ALL_ELEMENTS);
2632       for (int j=0; j<TotalNumber; j++)
2633         MEDArrayNodeFamily[Number[j]-1]=FamilyIdentifier;
2634     }
2635     err=med_2_3::MEDmeshEntityFamilyNumberWr(_medIdt,_meshName.c_str(),MED_NO_DT,MED_NO_IT,med_2_3::MED_NODE,MED_NONE,NumberOfNodes,MEDArrayNodeFamily);
2636
2637
2638     if ( err != MED_VALID)
2639       throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't write node family for the |"<< NumberOfNodes
2640                                    << "| nodes in mesh |"
2641                                    << _ptrMesh->_name.c_str() << "|" ));
2642     delete[] MEDArrayNodeFamily;
2643   }
2644
2645   { // CELLS RELATED BLOCK
2646     medEntityMesh entity=MED_EN::MED_CELL;
2647     // SOLUTION TEMPORAIRE CAR _ptrMesh->_MEDArray____Family DOIT ETRE ENLEVER DE LA CLASSE MESH
2648     if ((_ptrMesh->getIsAGrid()) || // PAL18712, GRID::existConnectivity() calls GRID::fillConnectivity() but it is not needed for writing GRID
2649         (((MESH*)_ptrMesh)->existConnectivity(MED_NODAL,entity)) ||
2650         (((MESH*)_ptrMesh)->existConnectivity(MED_DESCENDING,entity)))
2651     {
2652       int numberOfTypes                 = _ptrMesh->getNumberOfTypes(entity);
2653       const medGeometryElement  * types = _ptrMesh->getTypes(entity);
2654
2655       // We build the array from the families list objects :
2656       int NumberOfElements = _ptrMesh->getNumberOfElements(entity, MED_ALL_ELEMENTS);
2657       int * MEDArrayFamily = new int[NumberOfElements];
2658       // family 0 by default
2659       for (int i=0; i<NumberOfElements; i++)
2660         MEDArrayFamily[i]=0;
2661       vector<FAMILY*> * myFamilies = &_ptrMesh->_familyCell;
2662       int NumberOfFamilies = myFamilies->size();
2663       if (0 == NumberOfFamilies) {
2664         vector<GROUP*> myGroups = _ptrMesh->getGroups(entity);
2665         groupFamilyConverter(myGroups,*myFamilies);
2666         NumberOfFamilies=myFamilies->size();
2667       }
2668       for (int i=0; i<NumberOfFamilies; i++) {
2669         int FamilyIdentifier = (*myFamilies)[i]->getIdentifier();
2670         int TotalNumber = (*myFamilies)[i]->getNumberOfElements(MED_ALL_ELEMENTS);
2671         const int * Number = (*myFamilies)[i]->getNumber(MED_ALL_ELEMENTS);
2672         for (int ii=0; ii<TotalNumber; ii++)
2673           MEDArrayFamily[Number[ii]-1]=FamilyIdentifier;
2674       }
2675
2676       int offset=0;
2677 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64)
2678       vector < med_2_3::med_int > temp( MEDArrayFamily, MEDArrayFamily + NumberOfElements );
2679 #endif
2680       for (int i=0; i<numberOfTypes; i++)
2681       {
2682         int typeNumberOfElements=_ptrMesh->getNumberOfElements(entity,types[i]);
2683 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64)
2684         err=med_2_3::MEDmeshEntityFamilyNumberWr(_medIdt,_meshName.c_str(),MED_NO_DT,MED_NO_IT,med_2_3::MED_CELL,(med_2_3::med_geometry_type) types[i],typeNumberOfElements,&temp[0]+offset);
2685 #else
2686         err=med_2_3::MEDmeshEntityFamilyNumberWr(_medIdt,_meshName.c_str(),MED_NO_DT,MED_NO_IT,med_2_3::MED_CELL,(med_2_3::med_geometry_type) types[i],typeNumberOfElements,MEDArrayFamily+offset);
2687 #endif
2688         MESSAGE_MED("OK "<<i);
2689         if ( err != MED_VALID)
2690           throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't write family for the |"<< typeNumberOfElements
2691                                        << "| cells of geometric type |" << geoNames[types[i]] <<"|in mesh |"
2692                                        << _ptrMesh->_name.c_str() << "|" ));
2693         offset+=typeNumberOfElements;
2694       }
2695       delete[] MEDArrayFamily;
2696     }
2697   }
2698
2699   if (!_ptrMesh->getIsAGrid() || _ptrMesh->getMeshDimension() == 3 ) // for grid - only in 3D mesh
2700
2701   { // FACE RELATED BLOCK
2702     medEntityMesh entity=MED_EN::MED_FACE;
2703     // SOLUTION TEMPORAIRE CAR _ptrMesh->_MEDArray____Family DOIT ETRE ENLEVER DE LA CLASSE MESH
2704     if ((_ptrMesh->getIsAGrid()) || // PAL18712, GRID::existConnectivity() calls GRID::fillConnectivity() but it is not needed for writing GRID
2705         (((MESH*)_ptrMesh)->existConnectivity(MED_NODAL,entity)) ||
2706         (((MESH*)_ptrMesh)->existConnectivity(MED_DESCENDING,entity)))
2707     {
2708       int numberOfTypes                 = _ptrMesh->getNumberOfTypes(entity);
2709       const medGeometryElement  * types = _ptrMesh->getTypes(entity);
2710       SCRUTE_MED(numberOfTypes);
2711
2712       int numberOfElements = _ptrMesh->getNumberOfElements(entity, MED_ALL_ELEMENTS);
2713       int * familyArray = new int[numberOfElements];
2714       for (int i=0;i<numberOfElements;i++)
2715         familyArray[i]=0;
2716
2717       int numberOfFamilies = _ptrMesh->getNumberOfFamilies(entity);
2718       vector<FAMILY*> * myFamilies = &_ptrMesh->_familyFace;
2719       if (0 == numberOfFamilies) {
2720         vector<GROUP*> myGroups = _ptrMesh->getGroups(entity);
2721
2722         groupFamilyConverter(myGroups,*myFamilies);
2723
2724         numberOfFamilies=myFamilies->size();
2725       }
2726       for (int i=0;i<numberOfFamilies;i++) {
2727         int familyNumber = (*myFamilies)[i]->getIdentifier();
2728         int numberOfFamilyElements = (*myFamilies)[i]->getNumberOfElements(MED_ALL_ELEMENTS);
2729         const int * myFamilyElements = (*myFamilies)[i]->getNumber(MED_ALL_ELEMENTS);
2730         for (int ii=0;ii<numberOfFamilyElements;ii++)
2731           familyArray[myFamilyElements[ii]-1]=familyNumber;
2732       }
2733
2734       for (int i=0;i<numberOfElements;i++)
2735         SCRUTE_MED(familyArray[i]);
2736
2737 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64)
2738       vector< med_2_3::med_int > temp( familyArray, familyArray + numberOfElements);
2739 #endif
2740       int offset=0;
2741       for (int i=0; i<numberOfTypes; i++)
2742       {
2743         int typeNumberOfElements = _ptrMesh->getNumberOfElements(entity,types[i]);
2744 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64)
2745         err=med_2_3::MEDmeshEntityFamilyNumberWr(_medIdt,_meshName.c_str(),MED_NO_DT,MED_NO_IT,med_2_3::MED_CELL,(med_2_3::med_geometry_type) types[i],typeNumberOfElements,&temp[0]+offset);
2746 #else
2747         err=med_2_3::MEDmeshEntityFamilyNumberWr(_medIdt,_meshName.c_str(),MED_NO_DT,MED_NO_IT,med_2_3::MED_CELL,(med_2_3::med_geometry_type) types[i],typeNumberOfElements,familyArray+offset);
2748 #endif
2749         if ( err != MED_VALID)
2750           {
2751             if ( _ptrMesh->getIsAGrid() )
2752               {
2753                 if ( numberOfFamilies > 0 )
2754                   throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<
2755                                                "Groups and families of FACEs in the structured "
2756                                                "mesh are not supported by med file" ));
2757               }
2758             else
2759               {
2760                 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<
2761                                              "Can't write family for the |"<< typeNumberOfElements
2762                                              << "| faces of geometric type |" << geoNames[types[i]]
2763                                              << "| in mesh |" << _meshName << "|" ));
2764               }
2765           }
2766         offset+=typeNumberOfElements;
2767       }
2768       delete[] familyArray;
2769     }
2770   }
2771
2772   if (!_ptrMesh->getIsAGrid() || _ptrMesh->getMeshDimension() > 1 ) // for grid - only in 3D and 2D mesh
2773
2774   { // EDGE RELATED BLOCK
2775     medEntityMesh entity=MED_EN::MED_EDGE;
2776     // SOLUTION TEMPORAIRE CAR _ptrMesh->_MEDArray____Family DOIT ETRE ENLEVER DE LA CLASSE MESH
2777     if  ((_ptrMesh->getIsAGrid()) || // PAL18712, GRID::existConnectivity() calls GRID::fillConnectivity() but it is not needed for writing GRID
2778          (((MESH*)_ptrMesh)->existConnectivity(MED_NODAL,entity) ) ||
2779          (((MESH*)_ptrMesh)->existConnectivity(MED_DESCENDING,entity) ) ) {
2780
2781       int numberOfTypes           = _ptrMesh->getNumberOfTypes (entity);
2782       const medGeometryElement  * types = _ptrMesh->getTypes         (entity);
2783
2784       int numberOfElements = _ptrMesh->getNumberOfElements(entity, MED_ALL_ELEMENTS);
2785       int * familyArray = new int[numberOfElements];
2786       for (int i=0;i<numberOfElements;i++)
2787         familyArray[i]=0;
2788
2789       int numberOfFamilies = _ptrMesh->getNumberOfFamilies(entity);
2790       vector<FAMILY*> * myFamilies = &_ptrMesh->_familyEdge;
2791       if (0 == numberOfFamilies) {
2792         vector<GROUP*> myGroups = _ptrMesh->getGroups(entity);
2793
2794         groupFamilyConverter(myGroups,*myFamilies);
2795
2796         numberOfFamilies=myFamilies->size();
2797
2798       }
2799
2800       for (int i=0;i<numberOfFamilies;i++) {
2801         int familyNumber = (*myFamilies)[i]->getIdentifier();
2802         int numberOfFamilyElements = (*myFamilies)[i]->getNumberOfElements(MED_ALL_ELEMENTS);
2803         const int * myFamilyElements = (*myFamilies)[i]->getNumber(MED_ALL_ELEMENTS);
2804         for (int ii=0;ii<numberOfFamilyElements;ii++)
2805           familyArray[myFamilyElements[ii]-1]=familyNumber;
2806       }
2807
2808
2809       for (int i=0;i<numberOfElements;i++)
2810         SCRUTE_MED(familyArray[i]);
2811
2812
2813       int typeCount = 0;
2814 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64)
2815       vector< med_2_3::med_int > temp (familyArray, familyArray+numberOfElements );
2816 #endif
2817
2818       for (int i=0; i<numberOfTypes; i++)
2819         {
2820           int typeNumberOfElements = _ptrMesh->getNumberOfElements(entity, types[i]);
2821 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64)
2822           err=med_2_3::MEDmeshEntityFamilyNumberWr(_medIdt,_meshName.c_str(),MED_NO_DT,MED_NO_IT,med_2_3::MED_CELL,(med_2_3::med_geometry_type) types[i],typeNumberOfElements,&temp[0]+typeCount);
2823 #else
2824           err=med_2_3::MEDmeshEntityFamilyNumberWr(_medIdt,_meshName.c_str(),MED_NO_DT,MED_NO_IT,med_2_3::MED_CELL,(med_2_3::med_geometry_type) types[i],typeNumberOfElements,familyArray+typeCount);
2825 #endif
2826           if ( err != MED_VALID)
2827             {
2828               if ( _ptrMesh->getIsAGrid() )
2829                 {
2830                   if ( numberOfFamilies > 0 )
2831                     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<
2832                                                  "Groups and families of EDGEs in the structured "
2833                                                  " mesh are not supported by med file" ));
2834                 }
2835               else
2836                 {
2837                   throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<  "Can't write family for the |"
2838                                                << _ptrMesh->getNumberOfElements(entity, types[i])
2839                                                << "| edges of geometric type |"
2840                                                << geoNames[types[i]] <<"|in mesh |"
2841                                                << _ptrMesh->_name.c_str() << "|" ));
2842                 }
2843             }
2844           typeCount += typeNumberOfElements;
2845         }
2846       delete[] familyArray;
2847     }
2848   }
2849
2850   END_OF_MED(LOC);
2851   return MED_VALID;
2852 }
2853
2854 int MED_MESH_WRONLY_DRIVER::writeFamilies(vector<FAMILY*> & families ) const
2855 {
2856
2857   const char * LOC="int MED_MESH_WRONLY_DRIVER::writeFamilies(vector<FAMILY*> families) const : ";
2858   BEGIN_OF_MED(LOC);
2859
2860   med_2_3::med_err err;
2861
2862   MESSAGE_MED(LOC<<" families.size() :"<<families.size());
2863
2864   for (unsigned int i=0; i< families.size(); i++) {
2865
2866     int      numberOfAttributes = families[i]->getNumberOfAttributes ();
2867     string   attributesDescriptions (numberOfAttributes*MED_COMMENT_SIZE,'\0');
2868
2869     // Recompose the attributes descriptions arg for MED
2870     for (int j=0; j < numberOfAttributes; j++)
2871     {
2872       string attributeDescription = families[i]->getAttributeDescription(j+1);
2873
2874       if ( attributeDescription.size() > MED_COMMENT_SIZE )
2875         throw MEDEXCEPTION( LOCALIZED(STRING(LOC) << "The size of the attribute description n° |"
2876                                       << j+1 << "| of the family |" << families[i]->getName()
2877                                       << "| with identifier |" << families[i]->getIdentifier()
2878                                       << "| is |" << attributeDescription.size()
2879                                       <<"| and is more than |" <<  MED_COMMENT_SIZE << "|"));
2880
2881       int length = min(MED_COMMENT_SIZE,(int)attributeDescription.size());
2882       attributesDescriptions.replace(j*MED_COMMENT_SIZE,length, attributeDescription,0,length);
2883     }
2884
2885
2886     int      numberOfGroups  = families[i]->getNumberOfGroups();
2887     string   groupsNames(numberOfGroups*MED_LNAME_SIZE,'\0');
2888
2889     // Recompose the groups names arg for MED
2890     for (int j=0; j < numberOfGroups; j++)
2891     {
2892       string groupName = families[i]->getGroupName(j+1);
2893
2894       if ( groupName.size() > MED_LNAME_SIZE )
2895         throw MEDEXCEPTION( LOCALIZED(STRING(LOC) << "The size of the group name  n° |"
2896                                       << j+1 << "| of the family |" << families[i]->getName()
2897                                       << "| with identifier |" << families[i]->getIdentifier()
2898                                       << "| is |" << groupName.size()
2899                                       <<"| and is more than |" << MED_LNAME_SIZE  << "|"));
2900
2901       int length = min(MED_LNAME_SIZE,(int)groupName.size());
2902       groupsNames.replace(j*MED_LNAME_SIZE,length, groupName,0,length);
2903     }
2904
2905     // test if the family already exists (HDF trick waiting a MED evolution to be replaced)
2906
2907     string dataGroupFam;
2908     if (families[i]->getEntity() == MED_NODE)
2909       dataGroupFam = "/ENS_MAA/"+_meshName+"/FAS/NOEUD/"+families[i]->getName()+"/";
2910     else
2911       dataGroupFam = "/ENS_MAA/"+_meshName+"/FAS/ELEME/"+families[i]->getName()+"/";
2912
2913     SCRUTE_MED("|"<<dataGroupFam<<"|");
2914     err = med_2_3::_MEDdatagroupOuvrir(_medIdt,const_cast <char *> (dataGroupFam.c_str()) );
2915     if ( err < MED_VALID ) {
2916       SCRUTE_MED(err);
2917       if ( families[i]->getName().size() > MED_NAME_SIZE )
2918         throw MEDEXCEPTION
2919           ( LOCALIZED(STRING(LOC) << "The size of the name of the family |" << i+1
2920                       << "| |" << families[i]->getName()
2921                       << "| with identifier |" << families[i]->getIdentifier()  << "| is |"
2922                       <<  families[i]->getName().size()  <<"| and is more than |"
2923                       << MED_NAME_SIZE << "|"));
2924
2925       MESSAGE_MED(LOC<<"families[i]->getName().c_str() : "<<families[i]->getName().c_str());
2926       MESSAGE_MED(LOC<<"_meshName.c_str() : "<<_meshName.c_str());
2927       MESSAGE_MED(LOC<<"families[i]->getIdentifier() : "<<families[i]->getIdentifier());
2928       MESSAGE_MED(LOC<<"numberOfAttributes : "<<numberOfAttributes);
2929
2930       MESSAGE_MED(LOC<<"attributesDescriptions.c_str() : "<<attributesDescriptions.c_str());
2931       MESSAGE_MED(LOC<<"numberOfGroups : "<<numberOfGroups);
2932       MESSAGE_MED(LOC<<"groupsNames.c_str() : "<<groupsNames.c_str());
2933 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64)
2934       int lgth=families[i]->getNumberOfAttributes();
2935       med_2_3::med_int *  AttributesIdentifier2 = new med_2_3::med_int[lgth];
2936       med_2_3::med_int *  AttributesValues2     = new med_2_3::med_int[lgth];
2937       for(med_2_3::med_int i2=0;i2<lgth;i2++)
2938         {
2939           AttributesIdentifier2[i2]=(med_2_3::med_int)(families[i]->getAttributesIdentifiers()[i2]);
2940           AttributesValues2[i2]=(med_2_3::med_int)(families[i]->getAttributesValues()[i2]);
2941         }
2942       err = med_2_3::MEDfamilyCr(_medIdt,_meshName.c_str(),healName(families[i]->getName()).c_str(),
2943                                  families[i]->getIdentifier(),numberOfGroups,groupsNames.c_str());
2944       /*err = med_2_3::MEDfamCr( _medIdt,
2945                               const_cast <char *> ( _meshName.c_str() ),
2946                               const_cast <char *> ( healName(families[i]->getName()).c_str() ),
2947                               families[i]->getIdentifier(),
2948                               AttributesIdentifier2,
2949                               AttributesValues2,
2950                               const_cast <char *> (attributesDescriptions.c_str()),
2951                               numberOfAttributes,
2952                               const_cast <char *> (groupsNames.c_str()),
2953                               numberOfGroups);*/
2954       delete [] AttributesIdentifier2;
2955       delete [] AttributesValues2;
2956 #else
2957       err = med_2_3::MEDfamilyCr(_medIdt,_meshName.c_str(),healName(families[i]->getName()).c_str(),
2958                                  families[i]->getIdentifier(),numberOfGroups,groupsNames.c_str());
2959       /*const_cast <char *> ( healName(families[i]->getName()).c_str() ),
2960         families[i]->getIdentifier(),
2961         (med_2_3::med_int*)families[i]->getAttributesIdentifiers(),
2962         (med_2_3::med_int*)families[i]->getAttributesValues(),
2963         const_cast <char *> (attributesDescriptions.c_str()),
2964         numberOfAttributes,
2965         const_cast <char *> (groupsNames.c_str()),
2966         numberOfGroups); -------- attributes for MED3 ...*/
2967 #endif
2968       SCRUTE_MED(err);
2969       if (err != MED_VALID)
2970         throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't create family |" << families[i]->getName()
2971                                      << "| with identifier |" << families[i]->getIdentifier()
2972                                      << "| groups names |" << groupsNames
2973                                      << "| and  attributes descriptions |" << attributesDescriptions << "|"));
2974     }
2975     else
2976       med_2_3::_MEDdatagroupFermer(_medIdt);
2977
2978   }
2979
2980   END_OF_MED(LOC);
2981
2982   return MED_VALID;
2983 }
2984
2985
2986
2987
2988 /*--------------------- RDWR PART -------------------------------*/
2989
2990 MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER()
2991 {
2992   this->GENDRIVER::_accessMode = MED_EN::RDWR;
2993 }
2994
2995 MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER(const string & fileName,
2996                                            GMESH *        ptrMesh):
2997   MED_MESH_DRIVER(fileName,ptrMesh,RDWR),
2998   MED_MESH_RDONLY_DRIVER(fileName,ptrMesh),
2999   MED_MESH_WRONLY_DRIVER(fileName,ptrMesh)
3000 {
3001   MESSAGE_MED("MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
3002 }
3003
3004 MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER(const MED_MESH_RDWR_DRIVER & driver):
3005   MED_MESH_DRIVER(driver),
3006   MED_MESH_RDONLY_DRIVER(driver),
3007   MED_MESH_WRONLY_DRIVER(driver)
3008 {
3009 }
3010
3011 MED_MESH_RDWR_DRIVER::~MED_MESH_RDWR_DRIVER()
3012 {
3013   //MESSAGE_MED("MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed");
3014 }
3015
3016 GENDRIVER * MED_MESH_RDWR_DRIVER::copy(void) const
3017 {
3018   return new MED_MESH_RDWR_DRIVER(*this);
3019 }
3020
3021 void MED_MESH_RDWR_DRIVER::write(void) const
3022 {
3023   MED_MESH_WRONLY_DRIVER::write();
3024 }
3025 void MED_MESH_RDWR_DRIVER::read (void)
3026 {
3027   MED_MESH_RDONLY_DRIVER::read();
3028 }