Salome HOME
5c4c83580981bb1934501d294acefa4e45a7af9d
[modules/med.git] / src / MEDMEM / MEDMEM_GMesh.cxx
1 // Copyright (C) 2007-2013  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 // File      : MEDMEM_GMesh.cxx
23 // Created   : Fri Jul 23 12:32:18 2010
24 // Author    : Edward AGAPOV (eap)
25 //
26
27 #include "MEDMEM_GMesh.hxx"
28
29 #include "MEDMEM_Family.hxx"
30 #include "MEDMEM_Group.hxx"
31 #include "MEDMEM_DriverFactory.hxx"
32
33 using namespace MEDMEM;
34 using namespace MED_EN;
35 using namespace std;
36
37 /*!
38 \defgroup GMESH_general MESH General information
39 These methods are related to the retrieval of general information about the mesh.
40
41 \defgroup MESH_families Families and Groups handling
42 The methods described in this section enable the manipulation of families and groups. These
43 notions define subsets of MED elements in a mesh. They differ because families are non
44 overlapping (a mesh element is associated to zero or one family)  while groups are more general.
45
46 \defgroup MESH_io Mesh I/O
47 These methods describe how to read and write meshes. Generally speaking, meshes should be read
48 via a constructor and should be written with the write() method.
49
50 */
51
52 //================================================================================
53 /*! Create an empty GMESH. */
54 //================================================================================
55
56 GMESH::GMESH()
57 {
58   init();
59 }
60
61 //================================================================================
62 /*!
63   Copy constructor
64 */
65 //================================================================================
66
67 GMESH::GMESH(GMESH &m)
68 {
69   _name = m._name;
70   _description = m._description;
71   _spaceDimension = m._spaceDimension;
72
73   _familyNode = m._familyNode;
74   for (int i=0; i<(int)m._familyNode.size(); i++)
75   {
76     _familyNode[i] = new FAMILY(* m._familyNode[i]);
77     _familyNode[i]->setMesh(this);
78     removeReference();
79   }
80
81   _familyCell = m._familyCell;
82   for (int i=0; i<(int)m._familyCell.size(); i++)
83   {
84     _familyCell[i] = new FAMILY(* m._familyCell[i]);
85     _familyCell[i]->setMesh(this);
86     removeReference();
87   }
88
89   _familyFace = m._familyFace;
90   for (int i=0; i<(int)m._familyFace.size(); i++)
91   {
92     _familyFace[i] = new FAMILY(* m._familyFace[i]);
93     _familyFace[i]->setMesh(this);
94     removeReference();
95   }
96
97   _familyEdge = m._familyEdge;
98   for (int i=0; i<(int)m._familyEdge.size(); i++)
99   {
100     _familyEdge[i] = new FAMILY(* m._familyEdge[i]);
101     _familyEdge[i]->setMesh(this);
102     removeReference();
103   }
104
105   _groupNode = m._groupNode;
106   for (int i=0; i<(int)m._groupNode.size(); i++)
107   {
108     _groupNode[i] = new GROUP(* m._groupNode[i]);
109     _groupNode[i]->setMesh(this);
110     removeReference();
111   }
112
113   _groupCell = m._groupCell;
114   for (int i=0; i<(int)m._groupCell.size(); i++)
115   {
116     _groupCell[i] = new GROUP(* m._groupCell[i]);
117     _groupCell[i]->setMesh(this);
118     removeReference();
119   }
120
121   _groupFace = m._groupFace;
122   for (int i=0; i<(int)m._groupFace.size(); i++)
123   {
124     _groupFace[i] = new GROUP(* m._groupFace[i]);
125     _groupFace[i]->setMesh(this);
126     removeReference();
127   }
128
129   _groupEdge = m._groupEdge;
130   for (int i=0; i<(int)m._groupEdge.size(); i++)
131   {
132     _groupEdge[i] = new GROUP(* m._groupEdge[i]);
133     _groupEdge[i]->setMesh(this);
134     removeReference();
135   }
136
137   //_drivers = m._drivers;  //Recopie des drivers?
138 }
139
140 //================================================================================
141 /*!
142  * \brief Destructor
143  */
144 //================================================================================
145
146 GMESH::~GMESH()
147 {
148   // if this is an automatic variable, be sure that destructor will be no more called
149   // due to cyclic dependencies with child reference counters (groups and families)
150   clearRefCouner();
151
152   for (unsigned i=0;i<_familyNode.size();i++)
153   {
154     // if another object refers to a family and it survive now,
155     // it sould not refer to a dead mesh
156     _familyNode[i]->setMesh(0);
157     _familyNode[i]->setMeshName( getName() );
158     _familyNode[i]->removeReference();
159   }
160   _familyNode.clear();
161   for (unsigned i=0;i<_familyCell.size();i++)
162   {
163     _familyCell[i]->setMesh(0);
164     _familyCell[i]->setMeshName( getName() );
165     _familyCell[i]->removeReference();
166   }
167   _familyCell.clear();
168   for (unsigned i=0;i<_familyFace.size();i++)
169   {
170     _familyFace[i]->setMesh(0);
171     _familyFace[i]->setMeshName( getName() );
172     _familyFace[i]->removeReference();
173   }
174   _familyFace.clear();
175   for (unsigned i=0;i<_familyEdge.size();i++)
176   {
177     _familyEdge[i]->setMesh(0);
178     _familyEdge[i]->setMeshName( getName() );
179     _familyEdge[i]->removeReference();
180   }
181   _familyEdge.clear();
182   for (unsigned i=0;i<_groupNode.size();i++)
183   {
184     _groupNode[i]->setMesh(0);
185     _groupNode[i]->setMeshName( getName() );
186     _groupNode[i]->removeReference();
187   }
188   _groupNode.clear();
189   for (unsigned i=0;i<_groupCell.size();i++)
190   {
191     _groupCell[i]->setMesh(0);
192     _groupCell[i]->setMeshName( getName() );
193     _groupCell[i]->removeReference();
194   }
195   _groupCell.clear();
196   for (unsigned i=0;i<_groupFace.size();i++)
197   {
198     _groupFace[i]->setMesh(0);
199     _groupFace[i]->setMeshName( getName() );
200     _groupFace[i]->removeReference();
201   }
202   _groupFace.clear();
203   for (unsigned i=0;i<_groupEdge.size();i++)
204   {
205     _groupEdge[i]->setMesh(0);
206     _groupEdge[i]->setMeshName( getName() );
207     _groupEdge[i]->removeReference();
208   }
209   _groupEdge.clear();
210
211   map<medEntityMesh,SUPPORT*>::iterator it = _entitySupport.begin();
212   for(;it!=_entitySupport.end();it++)
213     if((*it).second != NULL)
214     {
215       (*it).second->setMesh(0);
216       (*it).second->setMeshName( getName() );
217       (*it).second->removeReference();
218     }
219   _entitySupport.clear();
220
221   for (unsigned int index=0; index < _drivers.size(); index++ )
222     if ( _drivers[index] ) delete _drivers[index];
223   _drivers.clear();
224 }
225
226 //================================================================================
227 /*!
228  * \brief Initialization of fields
229  */
230 //================================================================================
231
232 void GMESH::init()
233 {
234   const char* LOC = "GMESH::init(): ";
235   BEGIN_OF_MED(LOC);
236
237   _name          ="NOT DEFINED";
238   _spaceDimension=MED_INVALID;
239   
240   END_OF_MED(LOC);
241 }
242
243 //================================================================================
244 /*!
245  * \brief Copy operator
246  */
247 //================================================================================
248
249 GMESH & GMESH::operator=(const GMESH &m)
250 {
251   const char* LOC = "GMESH & GMESH::operator=(const GMESH &m) : ";
252   BEGIN_OF_MED(LOC);
253   MESSAGE_MED("Not yet implemented");
254   END_OF_MED(LOC);
255
256   return *this;
257 }
258
259 //================================================================================
260 /*!
261  * \brief Comparison
262  */
263 //================================================================================
264
265 bool GMESH::operator==(const GMESH& other) const
266 {
267   return this==&other;
268 }
269
270 //================================================================================
271 /*!
272  * \brief Print operator
273  */
274 //================================================================================
275
276 ostream & MEDMEM::operator<<(ostream &os, const GMESH &myMesh)
277 {
278   myMesh.printMySelf(os);
279   return os;
280 }
281
282 /*! \if MEDMEM_ug
283 \addtogroup MESH_io
284 @{
285 \endif
286 */
287 //================================================================================
288 /*!
289  * \brief Add a %MESH driver of type %driverTypes (MED_DRIVER, ....) associated
290  *        with file fileName. The meshname used in the file is  driverName.
291  *        addDriver returns an integer handler.
292  */
293 //================================================================================
294
295 int  GMESH::addDriver(driverTypes            driverType,
296                       const std::string &    fileName,
297                       const std::string &    driverName,
298                       MED_EN::med_mode_acces access)
299 {
300   const char* LOC = "GMESH::addDriver(driverTypes driverType, const string & fileName=\"Default File Name.med\",const string & driverName=\"Default Mesh Name\",MED_EN::med_mode_acces access) : ";
301   BEGIN_OF_MED(LOC);
302
303   GENDRIVER * driver;
304
305   SCRUTE_MED(driverType);
306
307   driver = DRIVERFACTORY::buildDriverForMesh(driverType,fileName,this,driverName,access) ;
308
309   _drivers.push_back(driver);
310
311   int current = _drivers.size()-1;
312
313   _drivers[current]->setMeshName(driverName);
314
315   END_OF_MED(LOC);
316
317   return current;
318 }
319
320 //================================================================================
321 /*! Add an existing MESH driver. */
322 //================================================================================
323
324 int GMESH::addDriver(GENDRIVER & driver)
325 {
326   const char* LOC = "GMESH::addDriver(GENDRIVER &) : ";
327   BEGIN_OF_MED(LOC);
328
329   // For the case where driver does not know about me since it has been created through
330   // constructor witout parameters: create newDriver knowing me and get missing data
331   // from driver using merge()
332   //GENDRIVER * newDriver = driver.copy() ;
333   GENDRIVER* newDriver = DRIVERFACTORY::buildDriverForMesh(driver.getDriverType(),
334                                                            driver.getFileName(), this,
335                                                            driver.getMeshName(),
336                                                            driver.getAccessMode());
337   _drivers.push_back(newDriver);
338
339   int current = _drivers.size()-1;
340   driver.setId(current);
341
342   newDriver->merge( driver );
343   newDriver->setId( current );
344
345   return current;
346
347   END_OF_MED(LOC);
348 }
349
350 //================================================================================
351 /*! Remove an existing MESH driver. */
352 //================================================================================
353
354 void GMESH::rmDriver (int index/*=0*/)
355 {
356   const char * LOC = "GMESH::rmDriver (int index=0): ";
357   BEGIN_OF_MED(LOC);
358
359   if (index >= 0 && index < (int)_drivers.size() && _drivers[index])
360   {
361     delete _drivers[index];
362     _drivers[index] = 0;
363   }
364   else
365     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
366                                      << "The index given is invalid, index must be between  0 and  |"
367                                      << _drivers.size()
368                                      ));
369   END_OF_MED(LOC);
370 }
371
372 //================================================================================
373 /*!
374  * \brief Read mesh from the file using given driver
375  *  \param index - index of driver to use for reading
376  */
377 //================================================================================
378
379 void GMESH::read(int index)
380 {
381   const char * LOC = "GMESH::read(int index=0) : ";
382   BEGIN_OF_MED(LOC);
383
384   if (index >= 0 && index < (int)_drivers.size() && _drivers[index])
385   {
386     _drivers[index]->open();
387     try
388     {
389       _drivers[index]->read();
390     }
391     catch ( const MEDEXCEPTION& ex )
392     {
393       _drivers[index]->close();
394       throw ex;
395     }
396     _drivers[index]->close();
397   }
398   else
399     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
400                                      << "The index given is invalid, index must be between  0 and |"
401                                      << _drivers.size()
402                                      ));
403   END_OF_MED(LOC);
404 }
405
406 //================================================================================
407 /*!
408   Reads GMESH using the given driver.
409 */
410 //================================================================================
411
412 void GMESH::read(const GENDRIVER & driver)
413 {
414   // For the case where driver does not know about me since it has been created through
415   // constructor witout parameters: create newDriver knowing me and get missing data
416   // from driver using merge()
417   auto_ptr<GENDRIVER> newDriver( DRIVERFACTORY::buildDriverForMesh(driver.getDriverType(),
418                                                                    driver.getFileName(),
419                                                                    this,
420                                                                    driver.getMeshName(),
421                                                                    driver.getAccessMode()));
422   newDriver->merge( driver );
423
424   newDriver->open();
425   try
426   {
427     newDriver->read();
428   }
429   catch ( const MEDEXCEPTION& ex )
430   {
431     newDriver->close();
432     throw ex;
433   }
434   newDriver->close();
435 }
436
437 //================================================================================
438 /*!
439  * \brief Reads the GMESH
440  *  \param driverType - type of driver to use for reading
441  *  \param filename - file to read from
442  *  \param meshname - name of a mesh to read
443  */
444 //================================================================================
445
446 void GMESH::read(driverTypes        driverType,
447                  const std::string& filename,
448                  const std::string& meshname)
449 {
450   auto_ptr<GENDRIVER> newDriver( DRIVERFACTORY::buildDriverForMesh(driverType, filename,
451                                                                    this, meshname, RDONLY));
452   newDriver->open();
453   try
454   {
455     newDriver->read();
456   }
457   catch ( const MEDEXCEPTION& ex )
458   {
459     newDriver->close();
460     throw ex;
461   }
462   newDriver->close();
463 }
464
465 //================================================================================
466 /*! Writes all the content of the MESH using driver referenced by the integer handle returned by a \a addDriver call.
467
468   Example :
469 \verbatim
470 //...
471 // Attaching the driver to file "output.med", meshname "Mesh"
472 int driver_handle = mesh.addDriver(MED_DRIVER, "output.med", "Mesh");
473 // Writing the content of mesh to the file
474 mesh.write(driver_handle);
475 \endverbatim
476 */
477 //================================================================================
478
479 void GMESH::write(int index) const
480 {
481   const char * LOC = "GMESH::write(int index=0) : ";
482   BEGIN_OF_MED(LOC);
483
484   if ( index > -1 && index < (int)_drivers.size() && _drivers[index] )
485   {
486     _drivers[index]->open();
487     try
488     {
489       _drivers[index]->write();
490     }
491     catch ( const MEDEXCEPTION& ex )
492     {
493       _drivers[index]->close();
494       throw ex;
495     }
496     _drivers[index]->close();
497   }
498   else
499     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
500                                      << "The index given is invalid, index must be between  0 and |"
501                                      << _drivers.size()
502                                      ));
503   END_OF_MED(LOC);
504 }
505
506 //================================================================================
507 /*!
508   Writes all the content of the GMESH using the given driver.
509 */
510 //================================================================================
511
512 void GMESH::write(const GENDRIVER & driver, MED_EN::med_mode_acces medMode/*=MED_EN::WRONLY*/) const
513 {
514   // For the case where driver does not know about me since it has been created through
515   // constructor witout parameters: create newDriver knowing me and get missing data
516   // from driver using merge()
517   auto_ptr<GENDRIVER> newDriver( DRIVERFACTORY::buildDriverForMesh(driver.getDriverType(),
518                                                                    driver.getFileName(),
519                                                                    const_cast<GMESH*>( this ),
520                                                                    driver.getMeshName(),
521                                                                    MED_EN::WRONLY));
522   newDriver->merge( driver );
523 //   if ( newDriver->getDriverType() == MED_DRIVER )
524 //     newDriver->setAccessMode( MED_EN::med_mode_acces( getMedAccessMode( medMode )));
525
526   newDriver->open();
527   try
528   {
529     newDriver->write();
530   }
531   catch ( const MEDEXCEPTION& ex )
532   {
533     newDriver->close();
534     throw ex;
535   }
536   newDriver->close();
537 }
538
539 //================================================================================
540 /*!
541  * \brief Writes all the content of the GMESH
542  *  \param driverType - type of driver to use for writing
543  *  \param filename - file to write into
544  *  \param meshname - mesh name
545  *  \param medMode - file access mode
546  */
547 //================================================================================
548
549 void GMESH::write(driverTypes        driverType,
550                   const std::string& filename,
551                   const std::string& meshname,
552                   MED_EN::med_mode_acces medMode/*=MED_EN::WRONLY*/) const
553 {
554   auto_ptr<GENDRIVER> newDriver
555     ( DRIVERFACTORY::buildDriverForMesh(driverType, filename,
556                                         const_cast<GMESH*> ( this ),
557                                         meshname.empty() ? _name : meshname,
558                                         MED_EN::WRONLY));
559
560 //   if ( newDriver->getDriverType() == MED_DRIVER )
561 //     newDriver->setAccessMode( MED_EN::med_mode_acces( getMedAccessMode( medMode ) ));
562
563   newDriver->open();
564   try
565   {
566     newDriver->write();
567   }
568   catch ( const MEDEXCEPTION& ex )
569   {
570     newDriver->close();
571     throw ex;
572   }
573   newDriver->close();
574 }
575 /*! \if MEDMEM_ug @} \endif */
576
577 /*! \if MEDMEM_ug
578 \addtogroup MESH_general
579 @{
580 \endif
581 */
582
583 //================================================================================
584 /*!
585  * Sets the MESH name. Name should not exceed MED_TAILLE_NOM
586    length defined in Med (i.e. 32 characters).
587 */
588 //================================================================================
589
590 void GMESH::setName(std::string name)
591 {
592   _name=name; //NOM interne Ã  la classe
593 }
594
595 //================================================================================
596 /*!
597  *Gets the MESH name.
598  */
599 //================================================================================
600
601 string GMESH::getName() const
602 {
603   return _name;
604 }
605
606 //================================================================================
607 /*! Set the MESH description */
608 /*! \ifnot MEDMEM_ug
609 Sets the MESH description. Description should not exceed MED_TAILLE_DESC length defined in Med (i.e. 200 characters).
610 \endif */
611 //================================================================================
612
613 void GMESH::setDescription(std::string description)
614 {
615   _description = description; //NOM interne Ã  la classe
616 }
617
618 //================================================================================
619 /*! Gets the MESH description. The string returned contains
620   a short description of the mesh, which is stored for
621   information purposes only.*/
622 //================================================================================
623
624 string GMESH::getDescription() const
625 {
626   return _description;
627 }
628
629 //================================================================================
630 /*! Gets the dimension of the space in which the
631   mesh is described (2 for planar meshes, 3 for volumes and
632   3D surfaces) . */
633 //================================================================================
634
635 int GMESH::getSpaceDimension() const
636 {
637   return _spaceDimension;
638 }
639
640 /*! \if MEDMEM_ug
641 The retrieval of general information about a mesh is illustrated in the following C++ example. Its Python equivalent can be found in \a MESHgeneral.py.
642 This example illustrates how to retrieve the name, description, mesh and space dimensions.
643
644 \example MESHgeneral.cxx
645 @}
646 \endif
647 */
648
649 /*! \if MEDMEM_ug
650 \addtogroup MESH_families
651 @{
652 \endif
653 */
654 //================================================================================
655 /*!
656   Retrieves the number of families in the mesh for entity type \a entity
657 */
658 //================================================================================
659
660 int GMESH::getNumberOfFamilies (MED_EN::medEntityMesh entity) const
661 {
662   switch (entity) {
663   case MED_EN::MED_NODE : return _familyNode.size();
664   case MED_EN::MED_CELL : return _familyCell.size();
665   case MED_EN::MED_FACE : return _familyFace.size();
666   case MED_EN::MED_EDGE : return _familyEdge.size();
667   default :
668     throw MEDEXCEPTION("MESH::getNumberOfFamilies : Unknown entity");
669   }
670 }
671 //================================================================================
672 /*! Returns the families of type \a entity present in the mesh as a vector of pointers */
673 //================================================================================
674
675 const vector<MEDMEM::FAMILY*> GMESH::getFamilies(MED_EN::medEntityMesh entity) const
676 {
677   switch (entity) {
678   case MED_EN::MED_NODE : return _familyNode;
679   case MED_EN::MED_CELL : return _familyCell;
680   case MED_EN::MED_FACE : return _familyFace;
681   case MED_EN::MED_EDGE : return _familyEdge;
682   default :
683     throw MEDEXCEPTION("MESH::getFamilies : Unknown entity");
684   }
685 }
686
687 //================================================================================
688 /*!
689  * \brief Return a family
690  *  \param entity - entity of the family
691  *  \param i - index of the family
692  *  \retval const MEDMEM::FAMILY* - pointer to the family
693  */
694 //================================================================================
695
696 const MEDMEM::FAMILY* GMESH::getFamily(MED_EN::medEntityMesh entity, int i) const
697 {
698   if (i<=0)
699     throw MEDEXCEPTION("MESH::getFamily(i) : argument i must be > 0");
700   const vector<FAMILY*>* Family;
701   switch (entity) {
702   case MED_EN::MED_NODE : Family = &_familyNode; break;
703   case MED_EN::MED_CELL : Family = &_familyCell; break;
704   case MED_EN::MED_FACE : Family = &_familyFace; break;
705   case MED_EN::MED_EDGE : Family = &_familyEdge; break;
706   default :
707     throw MEDEXCEPTION("MESH::getFamilies : Unknown entity");
708   }
709   if (i>(int)Family->size())
710     throw MEDEXCEPTION("MESH::getFamily(entity,i) : argument i must be <= _numberOfFamilies");
711   return (*Family)[i-1];
712 }
713
714
715 //================================================================================
716 /*! Retrieves the number of groups in the mesh for entity type \a entity */
717 //================================================================================
718
719 int GMESH::getNumberOfGroups (MED_EN::medEntityMesh entity) const
720 {
721   switch (entity) {
722   case MED_EN::MED_NODE : return _groupNode.size();
723   case MED_EN::MED_CELL : return _groupCell.size();
724   case MED_EN::MED_FACE : return _groupFace.size();
725   case MED_EN::MED_EDGE : return _groupEdge.size();
726   default :
727     throw MEDEXCEPTION("MESH::getNumberOfGroups : Unknown entity");
728   }
729 }
730 //================================================================================
731 /*! Returns the groups of type \a entity present in the mesh as a vector of pointers. The GROUP class inheriting from the SUPPORT class, the
732   methods that can be used on these groups are explained in the related section.*/
733 //================================================================================
734
735 const vector<GROUP*> GMESH::getGroups(MED_EN::medEntityMesh entity) const
736 {
737   switch (entity) {
738   case MED_EN::MED_NODE : return _groupNode;
739   case MED_EN::MED_CELL : return _groupCell;
740   case MED_EN::MED_FACE : return _groupFace;
741   case MED_EN::MED_EDGE : return _groupEdge;
742   default :
743     throw MEDEXCEPTION("MESH::getGroups : Unknown entity");
744   }
745 }
746
747 //================================================================================
748 /*!
749  * \brief Return a group
750  *  \param entity - entity of the group
751  *  \param i - index of the group
752  *  \retval const GROUP* - pointer to the group
753  */
754 //================================================================================
755
756 const GROUP* GMESH::getGroup(MED_EN::medEntityMesh entity, int i) const
757 {
758   const char * LOC = "GMESH::getGroup(medEntityMesh entity, int i) : ";
759   if (i<=0)
760     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"argument i must be > 0"));
761   const vector<GROUP*>* Group = 0;
762   switch (entity) {
763   case MED_EN::MED_NODE : Group = &_groupNode; break;
764   case MED_EN::MED_CELL : Group = &_groupCell; break;
765   case MED_EN::MED_FACE : Group = &_groupFace; break;
766   case MED_EN::MED_EDGE : Group = &_groupEdge; break;
767   default :
768     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Unknown entity"));
769   }
770   if (i>(int)Group->size())
771     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"argument i="<<i<<" must be <= _numberOfGroups="<<Group->size()));
772   return (*Group)[i-1];
773 }
774
775 //================================================================================
776 /*! Retrieves the group named \a name.
777   The method browses all the entities in order to find the group.
778   If two groups with the same name coexist, the first one found will be
779   returned. If no group with the correct name is found, the method throws
780   an exception.
781 */
782 //================================================================================
783
784 const GROUP* GMESH::getGroup(const string& name) const  throw (MEDEXCEPTION)
785 {
786   const vector<GROUP*>* group_vectors [4]={&_groupNode, &_groupEdge,&_groupFace,&_groupCell};
787   for (int ientity=0;ientity<4;ientity++)
788     for (unsigned igroup=0; igroup< group_vectors[ientity]->size();igroup++)
789     {
790       const vector<GROUP*>& group_vect = *group_vectors[ientity];
791       GROUP* group=group_vect[igroup];
792       if (group->getName()==name)
793         return group;
794     }
795   cerr << "MESH::getGroup("<<name<<") : group "<<name <<" was not found"<<endl;
796   throw MEDEXCEPTION("MESH::getGroup(name) : name not found");
797 }
798
799 //================================================================================
800 /*!
801   Method returns a reference on a support defined on all the elements of an entity.
802 */
803 //================================================================================
804
805 const SUPPORT * GMESH::getSupportOnAll(medEntityMesh entity) const throw(MEDEXCEPTION)
806 {
807   const char * LOC = "GMESH::getSupportOnAll : " ;
808   BEGIN_OF_MED(LOC) ;
809   if(entity == MED_ALL_ENTITIES)
810     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined on entity MED_ALL_ENTITIES !"));
811
812   map<medEntityMesh,SUPPORT*>::const_iterator it =  _entitySupport.find(entity);
813
814   // find support and return is if exists
815   if(it != _entitySupport.end())
816     return (*it).second;
817   else
818     {
819       //build, store and return support
820       GMESH* thisMesh = const_cast< GMESH* >( this );
821       SUPPORT * aSupport = new SUPPORT;
822       string aSuppName = "SupportOnAll_"+entNames[entity];
823       aSupport->setName( aSuppName );
824       aSupport->setMesh( thisMesh );
825       aSupport->setEntity( entity );
826       aSupport->setAll( true );
827       aSupport->update();
828
829       thisMesh->_entitySupport.insert(make_pair(entity,aSupport));
830       thisMesh->removeReference();
831
832       return aSupport;
833     }
834 }
835
836 /*! \if MEDMEM_ug @} \endif */
837
838 /*! \if MEDMEM_ug
839 \addtogroup MESH_advanced
840 @{
841 \endif
842 */
843 //================================================================================
844 /*!
845   Return a SUPPORT pointer on the union of all SUPPORTs in Supports.
846   You should delete this pointer after use to avoid memory leaks.
847 */
848 //================================================================================
849
850 SUPPORT * GMESH::mergeSupports(const std::vector<SUPPORT *> Supports) throw (MEDEXCEPTION)
851 {
852   const char * LOC = "GMESH::mergeSupports(const vector<SUPPORT *> ) : " ;
853   BEGIN_OF_MED(LOC) ;
854
855   SUPPORT * returnedSupport;
856   string returnedSupportName;
857   string returnedSupportDescription;
858   char * returnedSupportNameChar;
859   char * returnedSupportDescriptionChar;
860   int size = Supports.size();
861
862   if (size == 0)
863     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) <<
864                                      " mergeSupports() does't accept zero size vector"));
865
866   if (size == 1)
867   {
868     MESSAGE_MED(LOC <<" there is only one SUPPORT in the argument list, the method return a copy of this object !");
869     SUPPORT * obj = const_cast <SUPPORT *> (Supports[0]);
870
871     returnedSupport = new SUPPORT(*obj);
872
873     int lenName = strlen((Supports[0]->getName()).c_str()) + 8 + 1;
874     int lenDescription = strlen((Supports[0]->getDescription()).c_str()) + 8 + 1;
875
876     returnedSupportNameChar = new char[lenName];
877     returnedSupportDescriptionChar = new char[lenDescription];
878
879     returnedSupportNameChar = strcpy(returnedSupportNameChar,"Copy of ");
880     returnedSupportNameChar = strcat(returnedSupportNameChar,(Supports[0]->getName()).c_str());
881     returnedSupportDescriptionChar = strcpy(returnedSupportDescriptionChar,"Copy of ");
882     returnedSupportDescriptionChar = strcat(returnedSupportDescriptionChar,
883                                             (Supports[0]->getDescription()).c_str());
884
885     returnedSupportName = string(returnedSupportNameChar);
886     returnedSupportDescription = string(returnedSupportDescriptionChar);
887
888     returnedSupport->setName(returnedSupportName);
889     returnedSupport->setDescription(returnedSupportDescription);
890
891     delete [] returnedSupportNameChar;
892     delete [] returnedSupportDescriptionChar;
893   }
894   else
895   {
896     SUPPORT * obj = const_cast <SUPPORT *> (Supports[0]);
897     returnedSupport = new SUPPORT(*obj);
898
899     int lenName = strlen((Supports[0]->getName()).c_str()) + 9 + 1;
900     int lenDescription = strlen((Supports[0]->getDescription()).c_str()) + 9 + 1;
901
902     for(int i = 1;i<size;i++)
903     {
904       obj = const_cast <SUPPORT *> (Supports[i]);
905       returnedSupport->blending(obj);
906
907       if (i == (size-1))
908       {
909         lenName = lenName + 5 + strlen((Supports[i]->getName()).c_str());
910         lenDescription = lenDescription + 5 +
911           strlen((Supports[i]->getDescription()).c_str());
912       }
913       else
914       {
915         lenName = lenName + 2 + strlen((Supports[i]->getName()).c_str());
916         lenDescription = lenDescription + 2 +
917           strlen((Supports[i]->getDescription()).c_str());
918       }
919     }
920
921     returnedSupportNameChar = new char[lenName];
922     returnedSupportDescriptionChar = new char[lenDescription];
923
924     returnedSupportNameChar = strcpy(returnedSupportNameChar,"Merge of ");
925     returnedSupportDescriptionChar = strcpy(returnedSupportDescriptionChar,"Merge of ");
926
927     returnedSupportNameChar = strcat(returnedSupportNameChar,(Supports[0]->getName()).c_str());
928     returnedSupportDescriptionChar = strcat(returnedSupportDescriptionChar,
929                                             (Supports[0]->getDescription()).c_str());
930
931     for(int i = 1;i<size;i++)
932     {
933       if (i == (size-1))
934       {
935         returnedSupportNameChar = strcat(returnedSupportNameChar," and ");
936         returnedSupportDescriptionChar = strcat(returnedSupportDescriptionChar," and ");
937
938         returnedSupportNameChar = strcat(returnedSupportNameChar,
939                                          (Supports[i]->getName()).c_str());
940         returnedSupportDescriptionChar = strcat(returnedSupportDescriptionChar,
941                                                 (Supports[i]->getDescription()).c_str());
942       }
943       else
944       {
945         returnedSupportNameChar = strcat(returnedSupportNameChar,", ");
946         returnedSupportNameChar = strcat(returnedSupportNameChar,
947                                          (Supports[i]->getName()).c_str());
948
949         returnedSupportDescriptionChar = strcat(returnedSupportDescriptionChar,", ");
950         returnedSupportDescriptionChar = strcat(returnedSupportDescriptionChar,
951                                                 (Supports[i]->getDescription()).c_str());
952       }
953     }
954
955     returnedSupportName = string(returnedSupportNameChar);
956     returnedSupport->setName(returnedSupportName);
957
958     returnedSupportDescription = string(returnedSupportDescriptionChar);
959     returnedSupport->setDescription(returnedSupportDescription);
960
961     delete [] returnedSupportNameChar;
962     delete [] returnedSupportDescriptionChar;
963   }
964
965   END_OF_MED(LOC);
966   return returnedSupport;
967 }
968
969 //================================================================================
970 /*!
971   return a SUPPORT pointer on the intersection of all SUPPORTs in Supports.
972   The (SUPPORT *) NULL pointer is returned if the intersection is empty.
973   You should delete this pointer after use to avois memory leaks.
974 */
975 //================================================================================
976
977 SUPPORT * GMESH::intersectSupports(const std::vector<SUPPORT *> Supports) throw (MEDEXCEPTION)
978 {
979   const char* LOC = "MESH:::intersectSupports(const vector<SUPPORT *> ) : ";
980   BEGIN_OF_MED(LOC);
981
982   SUPPORT * returnedSupport;
983   string returnedSupportName;
984   string returnedSupportDescription;
985   char * returnedSupportNameChar;
986   char * returnedSupportDescriptionChar;
987   int size = Supports.size();
988
989   if (size == 1)
990   {
991     MESSAGE_MED(PREFIX_MED <<" there is only one SUPPORT in the argument list, the method return a copy of this object !");
992     SUPPORT * obj = const_cast <SUPPORT *> (Supports[0]);
993
994     returnedSupport = new SUPPORT(*obj);
995
996     int lenName = strlen((Supports[0]->getName()).c_str()) + 8 + 1;
997     int lenDescription = strlen((Supports[0]->getDescription()).c_str()) + 8 + 1;
998
999     returnedSupportNameChar = new char[lenName];
1000     returnedSupportDescriptionChar = new char[lenDescription];
1001
1002     returnedSupportNameChar = strcpy(returnedSupportNameChar,"Copy of ");
1003     returnedSupportNameChar = strcat(returnedSupportNameChar,(Supports[0]->getName()).c_str());
1004     returnedSupportDescriptionChar = strcpy(returnedSupportDescriptionChar,"Copy of ");
1005     returnedSupportDescriptionChar = strcat(returnedSupportDescriptionChar,
1006                                             (Supports[0]->getDescription()).c_str());
1007
1008     returnedSupportName = string(returnedSupportNameChar);
1009     returnedSupportDescription = string(returnedSupportDescriptionChar);
1010
1011     returnedSupport->setName(returnedSupportName);
1012     returnedSupport->setDescription(returnedSupportDescription);
1013
1014     delete [] returnedSupportNameChar;
1015     delete [] returnedSupportDescriptionChar;
1016   }
1017   else
1018   {
1019     SUPPORT * obj = const_cast <SUPPORT *> (Supports[0]);
1020     returnedSupport = new SUPPORT(*obj);
1021
1022     int lenName = strlen((Supports[0]->getName()).c_str()) + 16 + 1;
1023     int lenDescription = strlen((Supports[0]->getDescription()).c_str()) + 16 + 1;
1024
1025     for(int i = 1;i<size;i++)
1026     {
1027       obj = const_cast <SUPPORT *> (Supports[i]);
1028       returnedSupport->intersecting(obj);
1029
1030       if (i == (size-1))
1031       {
1032         lenName = lenName + 5 + strlen((Supports[i]->getName()).c_str());
1033         lenDescription = lenDescription + 5 +
1034           strlen((Supports[i]->getDescription()).c_str());
1035       }
1036       else
1037       {
1038         lenName = lenName + 2 + strlen((Supports[i]->getName()).c_str());
1039         lenDescription = lenDescription + 2 +
1040           strlen((Supports[i]->getDescription()).c_str());
1041       }
1042     }
1043     if(returnedSupport != (SUPPORT *) NULL)
1044     {
1045       returnedSupportNameChar = new char[lenName];
1046       returnedSupportDescriptionChar = new char[lenDescription];
1047
1048       returnedSupportNameChar = strcpy(returnedSupportNameChar,
1049                                        "Intersection of ");
1050       returnedSupportDescriptionChar =
1051         strcpy(returnedSupportDescriptionChar,"Intersection of ");
1052
1053       returnedSupportNameChar = strcat(returnedSupportNameChar,
1054                                        (Supports[0]->getName()).c_str());
1055       returnedSupportDescriptionChar =
1056         strcat(returnedSupportDescriptionChar,
1057                (Supports[0]->getDescription()).c_str());
1058
1059       for(int i = 1;i<size;i++)
1060       {
1061         if (i == (size-1))
1062         {
1063           returnedSupportNameChar = strcat(returnedSupportNameChar,
1064                                            " and ");
1065           returnedSupportDescriptionChar =
1066             strcat(returnedSupportDescriptionChar," and ");
1067
1068           returnedSupportNameChar =
1069             strcat(returnedSupportNameChar,
1070                    (Supports[i]->getName()).c_str());
1071           returnedSupportDescriptionChar =
1072             strcat(returnedSupportDescriptionChar,
1073                    (Supports[i]->getDescription()).c_str());
1074         }
1075         else
1076         {
1077           returnedSupportNameChar = strcat(returnedSupportNameChar,
1078                                            ", ");
1079           returnedSupportNameChar =
1080             strcat(returnedSupportNameChar,
1081                    (Supports[i]->getName()).c_str());
1082
1083           returnedSupportDescriptionChar =
1084             strcat(returnedSupportDescriptionChar,", ");
1085           returnedSupportDescriptionChar =
1086             strcat(returnedSupportDescriptionChar,
1087                    (Supports[i]->getDescription()).c_str());
1088         }
1089       }
1090
1091       returnedSupportName = string(returnedSupportNameChar);
1092       returnedSupport->setName(returnedSupportName);
1093
1094       returnedSupportDescription = string(returnedSupportDescriptionChar);
1095       returnedSupport->setDescription(returnedSupportDescription);
1096
1097       delete [] returnedSupportNameChar;
1098       delete [] returnedSupportDescriptionChar;
1099     }
1100   }
1101
1102   END_OF_MED(LOC);
1103   return returnedSupport;
1104 }
1105
1106 /*! \if MEDMEM_ug
1107   @}
1108 \endif
1109 */
1110 /*!
1111   Method created to factorize code. This method creates a new support on entity 'entity' (to deallocate) containing all the entities contained in
1112   elements 'listOfElt' of entity 'entity'.
1113 */
1114 SUPPORT * GMESH::buildSupportOnElementsFromElementList(const list<int>& listOfElt, MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION)
1115 {
1116   const char* LOC = "GMESH::buildSupportOnElementsFromElementList : ";
1117   BEGIN_OF_MED(LOC);
1118   SUPPORT * mySupport = new SUPPORT();
1119   mySupport->setMesh((MESH *)this);
1120   mySupport->setName("Boundary");
1121   mySupport->setEntity( entity );
1122   mySupport->fillFromElementList(listOfElt);
1123   END_OF_MED(LOC);
1124   return mySupport ;
1125 }
1126
1127 // internal helper type
1128 struct _cell
1129 {
1130   std::vector<int> groups;
1131   MED_EN::medGeometryElement geometricType;
1132   // to have geometricType good for nodal groups when MESH::getNumberOfTypes(MED_NODE)==0
1133   _cell():geometricType(MED_POINT1) {}
1134 };
1135
1136 //================================================================================
1137 /*!
1138  * Create families from groups.
1139  * This function is automaticaly called whenever we ask for families that are not up-to-date.
1140  * (The creation of families is delayed to the need of user.)
1141  * If a new created family hapen to already exist, we keep the old one.
1142  * (There is no way to know which family has change.)
1143  */
1144 //================================================================================
1145
1146 void GMESH::createFamilies()
1147 {
1148   int idFamNode = 0; // identifier for node families
1149   int idFamElement = 0; // identifier for cell, face or edge families
1150
1151   // Main loop on mesh's entities
1152   for (medEntityMesh entity=MED_CELL; entity!=MED_ALL_ENTITIES; ++entity)
1153   {
1154     int numberofgroups = getNumberOfGroups(entity);
1155     if(!numberofgroups)
1156       continue; // no groups for this entity
1157
1158     vector< vector<FAMILY*> > whichFamilyInGroup(numberofgroups); // this container is used to update groups at the end
1159
1160     // make myFamilies points to the member corresponding to entity
1161     vector<FAMILY*>* myFamilies;
1162     switch ( entity )
1163     {
1164     case MED_CELL : myFamilies = & _familyCell; break;
1165     case MED_FACE : myFamilies = & _familyFace; break;
1166     case MED_EDGE : myFamilies = & _familyEdge; break;
1167     case MED_NODE : myFamilies = & _familyNode; break;
1168     }
1169
1170     vector<GROUP*> myGroups=getGroups(entity); // get a copy of the groups ptr for the entity
1171     // get a copy of the (old) family ptrs before clearing
1172     vector<FAMILY*> myOldFamilies=getFamilies(entity);
1173     myFamilies->clear();
1174
1175
1176     // 1 - Create a vector containing for each cell (of the entity) an information structure
1177     //     giving geometric type and the groups it belong to
1178
1179     med_int numberOfTypes=0;
1180     const medGeometryElement* geometricTypes = 0;
1181     if ( entity != MED_NODE)
1182     {
1183       numberOfTypes = getNumberOfTypes(entity);
1184       geometricTypes = getTypes(entity);
1185     }
1186     med_int numberOfCells=getNumberOfElements(entity, MED_ALL_ELEMENTS);  // total number of cells for that entity
1187     SCRUTE_MED(numberOfTypes);
1188     SCRUTE_MED(numberOfCells);
1189     vector< _cell > tab_cell(numberOfCells);
1190     vector< _cell >::iterator cell = tab_cell.begin();
1191     for(med_int t=0; t!=numberOfTypes; ++t)
1192     {
1193       int nbCellsOfType = getNumberOfElements(entity,geometricTypes[t]);
1194       for(int n=0; n!=nbCellsOfType; ++n, ++cell)
1195         cell->geometricType=geometricTypes[t];
1196     }
1197
1198     // 2 - Scan cells in groups and update in tab_cell the container of groups a cell belong to
1199
1200     for (unsigned g=0; g!=myGroups.size(); ++g)
1201     {
1202       // scan cells that belongs to the group
1203       const int* groupCells=myGroups[g]->getnumber()->getValue();
1204       int nbCells=myGroups[g]->getnumber()->getLength();
1205       for(int c=0; c!=nbCells; ++c)
1206         tab_cell[groupCells[c]-1].groups.push_back(g);
1207     }
1208
1209
1210     // 3 - Scan the cells vector, genarate family name, and create a map associating the family names
1211     //     whith the vector of contained cells
1212
1213     map< string,vector<int> > tab_families;
1214     map< string,vector<int> >::iterator fam;
1215     for(int n=0; n!=numberOfCells; ++n)
1216     {
1217       ostringstream key; // to generate the name of the family
1218       key << "FAM";
1219       if(tab_cell[n].groups.empty()) // this cell don't belong to any group
1220         key << "_NONE" << entity;
1221
1222       for(vector<int>::const_iterator it=tab_cell[n].groups.begin(); it!=tab_cell[n].groups.end(); ++it)
1223       {
1224         string groupName=myGroups[*it]->getName();
1225         if(groupName.empty())
1226           key << "_G" << *it;
1227         else
1228           key << "_" << groupName;
1229       }
1230
1231       tab_families[key.str()].push_back(n+1); // fill the vector of contained cells associated whith the family
1232     }
1233
1234
1235     // 4 - Scan the family map, create MED Families, check if it already exist.
1236
1237     for( fam=tab_families.begin(); fam!=tab_families.end(); ++fam)
1238     {
1239       vector<medGeometryElement> tab_types_geometriques;
1240       medGeometryElement geometrictype=MED_NONE;
1241       vector<int> tab_index_types_geometriques;
1242       vector<int> tab_nombres_elements;
1243       if ( fam->second.empty() )
1244         continue; // it is just a truncated long family name
1245
1246       // scan family cells and fill the tab that are needed by the create a MED FAMILY
1247       for( unsigned i=0; i!=fam->second.size(); ++i)
1248       {
1249         int ncell=fam->second[i]-1;
1250         if(tab_cell[ncell].geometricType != geometrictype)
1251         {
1252           // new geometric type -> we store it and complete index tabs
1253           if(!tab_index_types_geometriques.empty())
1254             tab_nombres_elements.push_back(i+1-tab_index_types_geometriques.back());
1255           tab_types_geometriques.push_back( (geometrictype=tab_cell[ncell].geometricType));
1256           tab_index_types_geometriques.push_back(i+1);
1257         }
1258       }
1259       // store and complete index tabs for the last geometric type
1260       tab_nombres_elements.push_back(fam->second.size()+1-tab_index_types_geometriques.back());
1261       tab_index_types_geometriques.push_back(fam->second.size()+1);
1262
1263       // family name sould not be longer than MED_TAILLE_NOM
1264       string famName = fam->first;
1265       if ( famName.size() > MED_NAME_SIZE ) {
1266         // try to cut off "FAM_" from the head
1267         if ( famName.size() - 4 <= MED_NAME_SIZE ) {
1268           famName = famName.substr(4);
1269         }
1270         else { // try to make a unique name by cutting off char by char from the tail
1271           famName = famName.substr(0, MED_NAME_SIZE);
1272           map< string,vector<int> >::iterator foundName = tab_families.find( famName );
1273           while ( !famName.empty() &&
1274                   ( foundName != tab_families.end() || famName[ famName.size()-1 ] == ' ' ))
1275           {
1276             famName = famName.substr( 0, famName.size() - 1 );
1277             foundName = tab_families.find( famName );
1278           }
1279         }
1280         tab_families[ famName ]; // add a new name in the table to assure uniqueness
1281       }
1282
1283       // create a MED FAMILY and fill it with the tabs we constructed
1284       FAMILY* newFam = new FAMILY();
1285       newFam->setName(famName);
1286       newFam->setMesh(this);
1287       removeReference();
1288       newFam->setNumberOfGeometricType(tab_types_geometriques.size());
1289       newFam->setGeometricType(&tab_types_geometriques[0]); // we know the tab is not empy
1290       newFam->setNumberOfElements(&tab_nombres_elements[0]);
1291       newFam->setNumber(&tab_index_types_geometriques[0],&fam->second[0]);
1292       newFam->setEntity(entity);
1293       newFam->setAll( getNumberOfElements( entity, MED_ALL_ELEMENTS ) == fam->second.size() );
1294
1295       int idFam = 0;
1296
1297       switch ( entity )
1298       {
1299       case MED_NODE :
1300         ++idFamNode;
1301         idFam = idFamNode;
1302         break;
1303       case MED_CELL :
1304       case MED_FACE :
1305       case MED_EDGE :
1306         ++idFamElement;
1307         idFam = -idFamElement;
1308         break;
1309       }
1310
1311       newFam->setIdentifier(idFam);
1312
1313       // Update links between families and groups
1314
1315       int ncell1=fam->second[0]-1;  // number of first cell in family
1316       int numberOfGroups=tab_cell[ncell1].groups.size(); // number of groups in the family
1317       if(numberOfGroups)
1318       {
1319         newFam->setNumberOfGroups(numberOfGroups);
1320         string * groupNames=new string[numberOfGroups];
1321
1322         // iterate on the groups the family belongs to
1323         vector<int>::const_iterator it=tab_cell[ncell1].groups.begin();
1324         for(int ng=0 ; it!=tab_cell[ncell1].groups.end(); ++it, ++ng)
1325         {
1326           whichFamilyInGroup[*it].push_back(newFam);
1327           groupNames[ng]=myGroups[*it]->getName();
1328         }
1329         newFam->setGroupsNames(groupNames);
1330         delete [] groupNames;
1331       }
1332
1333       MESSAGE_MED("  MESH::createFamilies() entity " << entity <<
1334                   " size " << myFamilies->size());
1335
1336       myFamilies->push_back(newFam);
1337     }
1338
1339     // delete old families
1340     for (unsigned int i=0;i<myOldFamilies.size();i++)
1341       myOldFamilies[i]->removeReference();
1342
1343     // update references in groups
1344     for (unsigned int i=0;i<myGroups.size();i++)
1345     {
1346       myGroups[i]->setNumberOfFamilies(whichFamilyInGroup[i].size());
1347       myGroups[i]->setFamilies(whichFamilyInGroup[i]);
1348     }
1349
1350     // re-scan the cells vector, and fill the family vector with cells.
1351     // creation of support, check if it already exist.
1352   }
1353 }
1354
1355 //================================================================================
1356 /*!
1357   Create groups from families.
1358
1359   It is used to create groups that have only one family
1360   for meshes that come from codes that use families instead
1361   of groups to define a subregion.
1362 */
1363 //================================================================================
1364
1365 void GMESH::createGroups()
1366 {
1367   for (medEntityMesh entity=MED_CELL; entity!=MED_ALL_ENTITIES; ++entity)
1368   {
1369     // make myFamilies points to the member corresponding to entity
1370     vector<FAMILY*>* myFamilies;
1371     vector<GROUP*>* myGroups;
1372     switch ( entity )
1373     {
1374     case MED_CELL :
1375       myFamilies = & _familyCell;
1376       myGroups = & _groupCell;
1377       break;
1378     case MED_FACE :
1379       myFamilies = & _familyFace;
1380       myGroups = & _groupFace;
1381       break;
1382     case MED_EDGE :
1383       myFamilies = & _familyEdge;
1384       myGroups = & _groupEdge;
1385       break;
1386     case MED_NODE :
1387       myFamilies = & _familyNode;
1388       myGroups = & _groupNode;
1389       break;
1390     }
1391
1392
1393     for (unsigned i=0; i< myFamilies->size(); i++)
1394     {
1395       list <FAMILY*> fam_list;
1396       fam_list.push_back((*myFamilies)[i]);
1397       //creates a group with the family name and only one family
1398       GROUP* group=new GROUP((*myFamilies)[i]->getName(),fam_list);
1399       (*myGroups).push_back(group);
1400       removeReference();
1401     }
1402   }
1403 }