1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : MEDMEM_GMesh.cxx
23 // Created : Fri Jul 23 12:32:18 2010
24 // Author : Edward AGAPOV (eap)
27 #include "MEDMEM_GMesh.hxx"
29 #include "MEDMEM_Family.hxx"
30 #include "MEDMEM_Group.hxx"
31 #include "MEDMEM_DriverFactory.hxx"
33 using namespace MEDMEM;
34 using namespace MED_EN;
38 \defgroup GMESH_general MESH General information
39 These methods are related to the retrieval of general information about the mesh.
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.
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.
52 //================================================================================
53 /*! Create an empty GMESH. */
54 //================================================================================
61 //================================================================================
65 //================================================================================
67 GMESH::GMESH(GMESH &m)
70 _description = m._description;
71 _spaceDimension = m._spaceDimension;
73 _familyNode = m._familyNode;
74 for (int i=0; i<(int)m._familyNode.size(); i++)
76 _familyNode[i] = new FAMILY(* m._familyNode[i]);
77 _familyNode[i]->setMesh(this);
81 _familyCell = m._familyCell;
82 for (int i=0; i<(int)m._familyCell.size(); i++)
84 _familyCell[i] = new FAMILY(* m._familyCell[i]);
85 _familyCell[i]->setMesh(this);
89 _familyFace = m._familyFace;
90 for (int i=0; i<(int)m._familyFace.size(); i++)
92 _familyFace[i] = new FAMILY(* m._familyFace[i]);
93 _familyFace[i]->setMesh(this);
97 _familyEdge = m._familyEdge;
98 for (int i=0; i<(int)m._familyEdge.size(); i++)
100 _familyEdge[i] = new FAMILY(* m._familyEdge[i]);
101 _familyEdge[i]->setMesh(this);
105 _groupNode = m._groupNode;
106 for (int i=0; i<(int)m._groupNode.size(); i++)
108 _groupNode[i] = new GROUP(* m._groupNode[i]);
109 _groupNode[i]->setMesh(this);
113 _groupCell = m._groupCell;
114 for (int i=0; i<(int)m._groupCell.size(); i++)
116 _groupCell[i] = new GROUP(* m._groupCell[i]);
117 _groupCell[i]->setMesh(this);
121 _groupFace = m._groupFace;
122 for (int i=0; i<(int)m._groupFace.size(); i++)
124 _groupFace[i] = new GROUP(* m._groupFace[i]);
125 _groupFace[i]->setMesh(this);
129 _groupEdge = m._groupEdge;
130 for (int i=0; i<(int)m._groupEdge.size(); i++)
132 _groupEdge[i] = new GROUP(* m._groupEdge[i]);
133 _groupEdge[i]->setMesh(this);
137 //_drivers = m._drivers; //Recopie des drivers?
140 //================================================================================
144 //================================================================================
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)
152 for (unsigned i=0;i<_familyNode.size();i++)
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();
161 for (unsigned i=0;i<_familyCell.size();i++)
163 _familyCell[i]->setMesh(0);
164 _familyCell[i]->setMeshName( getName() );
165 _familyCell[i]->removeReference();
168 for (unsigned i=0;i<_familyFace.size();i++)
170 _familyFace[i]->setMesh(0);
171 _familyFace[i]->setMeshName( getName() );
172 _familyFace[i]->removeReference();
175 for (unsigned i=0;i<_familyEdge.size();i++)
177 _familyEdge[i]->setMesh(0);
178 _familyEdge[i]->setMeshName( getName() );
179 _familyEdge[i]->removeReference();
182 for (unsigned i=0;i<_groupNode.size();i++)
184 _groupNode[i]->setMesh(0);
185 _groupNode[i]->setMeshName( getName() );
186 _groupNode[i]->removeReference();
189 for (unsigned i=0;i<_groupCell.size();i++)
191 _groupCell[i]->setMesh(0);
192 _groupCell[i]->setMeshName( getName() );
193 _groupCell[i]->removeReference();
196 for (unsigned i=0;i<_groupFace.size();i++)
198 _groupFace[i]->setMesh(0);
199 _groupFace[i]->setMeshName( getName() );
200 _groupFace[i]->removeReference();
203 for (unsigned i=0;i<_groupEdge.size();i++)
205 _groupEdge[i]->setMesh(0);
206 _groupEdge[i]->setMeshName( getName() );
207 _groupEdge[i]->removeReference();
211 map<medEntityMesh,SUPPORT*>::iterator it = _entitySupport.begin();
212 for(;it!=_entitySupport.end();it++)
213 if((*it).second != NULL)
215 (*it).second->setMesh(0);
216 (*it).second->setMeshName( getName() );
217 (*it).second->removeReference();
219 _entitySupport.clear();
221 for (unsigned int index=0; index < _drivers.size(); index++ )
222 if ( _drivers[index] ) delete _drivers[index];
226 //================================================================================
228 * \brief Initialization of fields
230 //================================================================================
234 const char* LOC = "GMESH::init(): ";
237 _name ="NOT DEFINED";
238 _spaceDimension=MED_INVALID;
243 //================================================================================
245 * \brief Copy operator
247 //================================================================================
249 GMESH & GMESH::operator=(const GMESH &m)
251 const char* LOC = "GMESH & GMESH::operator=(const GMESH &m) : ";
253 MESSAGE_MED("Not yet implemented");
259 //================================================================================
263 //================================================================================
265 bool GMESH::operator==(const GMESH& other) const
270 //================================================================================
272 * \brief Print operator
274 //================================================================================
276 ostream & MEDMEM::operator<<(ostream &os, const GMESH &myMesh)
278 myMesh.printMySelf(os);
287 //================================================================================
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.
293 //================================================================================
295 int GMESH::addDriver(driverTypes driverType,
296 const std::string & fileName,
297 const std::string & driverName,
298 MED_EN::med_mode_acces access)
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) : ";
305 SCRUTE_MED(driverType);
307 driver = DRIVERFACTORY::buildDriverForMesh(driverType,fileName,this,driverName,access) ;
309 _drivers.push_back(driver);
311 int current = _drivers.size()-1;
313 _drivers[current]->setMeshName(driverName);
320 //================================================================================
321 /*! Add an existing MESH driver. */
322 //================================================================================
324 int GMESH::addDriver(GENDRIVER & driver)
326 const char* LOC = "GMESH::addDriver(GENDRIVER &) : ";
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);
339 int current = _drivers.size()-1;
340 driver.setId(current);
342 newDriver->merge( driver );
343 newDriver->setId( current );
350 //================================================================================
351 /*! Remove an existing MESH driver. */
352 //================================================================================
354 void GMESH::rmDriver (int index/*=0*/)
356 const char * LOC = "GMESH::rmDriver (int index=0): ";
359 if (index >= 0 && index < (int)_drivers.size() && _drivers[index])
361 delete _drivers[index];
365 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
366 << "The index given is invalid, index must be between 0 and |"
372 //================================================================================
374 * \brief Read mesh from the file using given driver
375 * \param index - index of driver to use for reading
377 //================================================================================
379 void GMESH::read(int index)
381 const char * LOC = "GMESH::read(int index=0) : ";
384 if (index >= 0 && index < (int)_drivers.size() && _drivers[index])
386 _drivers[index]->open();
389 _drivers[index]->read();
391 catch ( const MEDEXCEPTION& ex )
393 _drivers[index]->close();
396 _drivers[index]->close();
399 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
400 << "The index given is invalid, index must be between 0 and |"
406 //================================================================================
408 Reads GMESH using the given driver.
410 //================================================================================
412 void GMESH::read(const GENDRIVER & driver)
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(),
420 driver.getMeshName(),
421 driver.getAccessMode()));
422 newDriver->merge( driver );
429 catch ( const MEDEXCEPTION& ex )
437 //================================================================================
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
444 //================================================================================
446 void GMESH::read(driverTypes driverType,
447 const std::string& filename,
448 const std::string& meshname)
450 auto_ptr<GENDRIVER> newDriver( DRIVERFACTORY::buildDriverForMesh(driverType, filename,
451 this, meshname, RDONLY));
457 catch ( const MEDEXCEPTION& ex )
465 //================================================================================
466 /*! Writes all the content of the MESH using driver referenced by the integer handle returned by a \a addDriver call.
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);
477 //================================================================================
479 void GMESH::write(int index) const
481 const char * LOC = "GMESH::write(int index=0) : ";
484 if ( index > -1 && index < (int)_drivers.size() && _drivers[index] )
486 _drivers[index]->open();
489 _drivers[index]->write();
491 catch ( const MEDEXCEPTION& ex )
493 _drivers[index]->close();
496 _drivers[index]->close();
499 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
500 << "The index given is invalid, index must be between 0 and |"
506 //================================================================================
508 Writes all the content of the GMESH using the given driver.
510 //================================================================================
512 void GMESH::write(const GENDRIVER & driver, MED_EN::med_mode_acces medMode/*=MED_EN::WRONLY*/) const
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(),
522 newDriver->merge( driver );
523 // if ( newDriver->getDriverType() == MED_DRIVER )
524 // newDriver->setAccessMode( MED_EN::med_mode_acces( getMedAccessMode( medMode )));
531 catch ( const MEDEXCEPTION& ex )
539 //================================================================================
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
547 //================================================================================
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
554 auto_ptr<GENDRIVER> newDriver
555 ( DRIVERFACTORY::buildDriverForMesh(driverType, filename,
556 const_cast<GMESH*> ( this ),
557 meshname.empty() ? _name : meshname,
560 // if ( newDriver->getDriverType() == MED_DRIVER )
561 // newDriver->setAccessMode( MED_EN::med_mode_acces( getMedAccessMode( medMode ) ));
568 catch ( const MEDEXCEPTION& ex )
575 /*! \if MEDMEM_ug @} \endif */
578 \addtogroup MESH_general
583 //================================================================================
585 * Sets the MESH name. Name should not exceed MED_TAILLE_NOM
586 length defined in Med (i.e. 32 characters).
588 //================================================================================
590 void GMESH::setName(std::string name)
592 _name=name; //NOM interne à la classe
595 //================================================================================
599 //================================================================================
601 string GMESH::getName() const
606 //================================================================================
607 /*! Set the MESH description */
609 Sets the MESH description. Description should not exceed MED_TAILLE_DESC length defined in Med (i.e. 200 characters).
611 //================================================================================
613 void GMESH::setDescription(std::string description)
615 _description = description; //NOM interne à la classe
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 //================================================================================
624 string GMESH::getDescription() const
629 //================================================================================
630 /*! Gets the dimension of the space in which the
631 mesh is described (2 for planar meshes, 3 for volumes and
633 //================================================================================
635 int GMESH::getSpaceDimension() const
637 return _spaceDimension;
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.
644 \example MESHgeneral.cxx
650 \addtogroup MESH_families
654 //================================================================================
656 Retrieves the number of families in the mesh for entity type \a entity
658 //================================================================================
660 int GMESH::getNumberOfFamilies (MED_EN::medEntityMesh entity) const
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();
668 throw MEDEXCEPTION("MESH::getNumberOfFamilies : Unknown entity");
671 //================================================================================
672 /*! Returns the families of type \a entity present in the mesh as a vector of pointers */
673 //================================================================================
675 const vector<MEDMEM::FAMILY*> GMESH::getFamilies(MED_EN::medEntityMesh entity) const
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;
683 throw MEDEXCEPTION("MESH::getFamilies : Unknown entity");
687 //================================================================================
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
694 //================================================================================
696 const MEDMEM::FAMILY* GMESH::getFamily(MED_EN::medEntityMesh entity, int i) const
699 throw MEDEXCEPTION("MESH::getFamily(i) : argument i must be > 0");
700 const vector<FAMILY*>* Family;
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;
707 throw MEDEXCEPTION("MESH::getFamilies : Unknown entity");
709 if (i>(int)Family->size())
710 throw MEDEXCEPTION("MESH::getFamily(entity,i) : argument i must be <= _numberOfFamilies");
711 return (*Family)[i-1];
715 //================================================================================
716 /*! Retrieves the number of groups in the mesh for entity type \a entity */
717 //================================================================================
719 int GMESH::getNumberOfGroups (MED_EN::medEntityMesh entity) const
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();
727 throw MEDEXCEPTION("MESH::getNumberOfGroups : Unknown entity");
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 //================================================================================
735 const vector<GROUP*> GMESH::getGroups(MED_EN::medEntityMesh entity) const
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;
743 throw MEDEXCEPTION("MESH::getGroups : Unknown entity");
747 //================================================================================
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
754 //================================================================================
756 const GROUP* GMESH::getGroup(MED_EN::medEntityMesh entity, int i) const
758 const char * LOC = "GMESH::getGroup(medEntityMesh entity, int i) : ";
760 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"argument i must be > 0"));
761 const vector<GROUP*>* Group = 0;
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;
768 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Unknown entity"));
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];
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
782 //================================================================================
784 const GROUP* GMESH::getGroup(const string& name) const throw (MEDEXCEPTION)
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++)
790 const vector<GROUP*>& group_vect = *group_vectors[ientity];
791 GROUP* group=group_vect[igroup];
792 if (group->getName()==name)
795 cerr << "MESH::getGroup("<<name<<") : group "<<name <<" was not found"<<endl;
796 throw MEDEXCEPTION("MESH::getGroup(name) : name not found");
799 //================================================================================
801 Method returns a reference on a support defined on all the elements of an entity.
803 //================================================================================
805 const SUPPORT * GMESH::getSupportOnAll(medEntityMesh entity) const throw(MEDEXCEPTION)
807 const char * LOC = "GMESH::getSupportOnAll : " ;
809 if(entity == MED_ALL_ENTITIES)
810 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined on entity MED_ALL_ENTITIES !"));
812 map<medEntityMesh,SUPPORT*>::const_iterator it = _entitySupport.find(entity);
814 // find support and return is if exists
815 if(it != _entitySupport.end())
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 );
829 thisMesh->_entitySupport.insert(make_pair(entity,aSupport));
830 thisMesh->removeReference();
836 /*! \if MEDMEM_ug @} \endif */
839 \addtogroup MESH_advanced
843 //================================================================================
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.
848 //================================================================================
850 SUPPORT * GMESH::mergeSupports(const std::vector<SUPPORT *> Supports) throw (MEDEXCEPTION)
852 const char * LOC = "GMESH::mergeSupports(const vector<SUPPORT *> ) : " ;
855 SUPPORT * returnedSupport;
856 string returnedSupportName;
857 string returnedSupportDescription;
858 char * returnedSupportNameChar;
859 char * returnedSupportDescriptionChar;
860 int size = Supports.size();
863 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) <<
864 " mergeSupports() does't accept zero size vector"));
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]);
871 returnedSupport = new SUPPORT(*obj);
873 int lenName = strlen((Supports[0]->getName()).c_str()) + 8 + 1;
874 int lenDescription = strlen((Supports[0]->getDescription()).c_str()) + 8 + 1;
876 returnedSupportNameChar = new char[lenName];
877 returnedSupportDescriptionChar = new char[lenDescription];
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());
885 returnedSupportName = string(returnedSupportNameChar);
886 returnedSupportDescription = string(returnedSupportDescriptionChar);
888 returnedSupport->setName(returnedSupportName);
889 returnedSupport->setDescription(returnedSupportDescription);
891 delete [] returnedSupportNameChar;
892 delete [] returnedSupportDescriptionChar;
896 SUPPORT * obj = const_cast <SUPPORT *> (Supports[0]);
897 returnedSupport = new SUPPORT(*obj);
899 int lenName = strlen((Supports[0]->getName()).c_str()) + 9 + 1;
900 int lenDescription = strlen((Supports[0]->getDescription()).c_str()) + 9 + 1;
902 for(int i = 1;i<size;i++)
904 obj = const_cast <SUPPORT *> (Supports[i]);
905 returnedSupport->blending(obj);
909 lenName = lenName + 5 + strlen((Supports[i]->getName()).c_str());
910 lenDescription = lenDescription + 5 +
911 strlen((Supports[i]->getDescription()).c_str());
915 lenName = lenName + 2 + strlen((Supports[i]->getName()).c_str());
916 lenDescription = lenDescription + 2 +
917 strlen((Supports[i]->getDescription()).c_str());
921 returnedSupportNameChar = new char[lenName];
922 returnedSupportDescriptionChar = new char[lenDescription];
924 returnedSupportNameChar = strcpy(returnedSupportNameChar,"Merge of ");
925 returnedSupportDescriptionChar = strcpy(returnedSupportDescriptionChar,"Merge of ");
927 returnedSupportNameChar = strcat(returnedSupportNameChar,(Supports[0]->getName()).c_str());
928 returnedSupportDescriptionChar = strcat(returnedSupportDescriptionChar,
929 (Supports[0]->getDescription()).c_str());
931 for(int i = 1;i<size;i++)
935 returnedSupportNameChar = strcat(returnedSupportNameChar," and ");
936 returnedSupportDescriptionChar = strcat(returnedSupportDescriptionChar," and ");
938 returnedSupportNameChar = strcat(returnedSupportNameChar,
939 (Supports[i]->getName()).c_str());
940 returnedSupportDescriptionChar = strcat(returnedSupportDescriptionChar,
941 (Supports[i]->getDescription()).c_str());
945 returnedSupportNameChar = strcat(returnedSupportNameChar,", ");
946 returnedSupportNameChar = strcat(returnedSupportNameChar,
947 (Supports[i]->getName()).c_str());
949 returnedSupportDescriptionChar = strcat(returnedSupportDescriptionChar,", ");
950 returnedSupportDescriptionChar = strcat(returnedSupportDescriptionChar,
951 (Supports[i]->getDescription()).c_str());
955 returnedSupportName = string(returnedSupportNameChar);
956 returnedSupport->setName(returnedSupportName);
958 returnedSupportDescription = string(returnedSupportDescriptionChar);
959 returnedSupport->setDescription(returnedSupportDescription);
961 delete [] returnedSupportNameChar;
962 delete [] returnedSupportDescriptionChar;
966 return returnedSupport;
969 //================================================================================
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.
975 //================================================================================
977 SUPPORT * GMESH::intersectSupports(const std::vector<SUPPORT *> Supports) throw (MEDEXCEPTION)
979 const char* LOC = "MESH:::intersectSupports(const vector<SUPPORT *> ) : ";
982 SUPPORT * returnedSupport;
983 string returnedSupportName;
984 string returnedSupportDescription;
985 char * returnedSupportNameChar;
986 char * returnedSupportDescriptionChar;
987 int size = Supports.size();
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]);
994 returnedSupport = new SUPPORT(*obj);
996 int lenName = strlen((Supports[0]->getName()).c_str()) + 8 + 1;
997 int lenDescription = strlen((Supports[0]->getDescription()).c_str()) + 8 + 1;
999 returnedSupportNameChar = new char[lenName];
1000 returnedSupportDescriptionChar = new char[lenDescription];
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());
1008 returnedSupportName = string(returnedSupportNameChar);
1009 returnedSupportDescription = string(returnedSupportDescriptionChar);
1011 returnedSupport->setName(returnedSupportName);
1012 returnedSupport->setDescription(returnedSupportDescription);
1014 delete [] returnedSupportNameChar;
1015 delete [] returnedSupportDescriptionChar;
1019 SUPPORT * obj = const_cast <SUPPORT *> (Supports[0]);
1020 returnedSupport = new SUPPORT(*obj);
1022 int lenName = strlen((Supports[0]->getName()).c_str()) + 16 + 1;
1023 int lenDescription = strlen((Supports[0]->getDescription()).c_str()) + 16 + 1;
1025 for(int i = 1;i<size;i++)
1027 obj = const_cast <SUPPORT *> (Supports[i]);
1028 returnedSupport->intersecting(obj);
1032 lenName = lenName + 5 + strlen((Supports[i]->getName()).c_str());
1033 lenDescription = lenDescription + 5 +
1034 strlen((Supports[i]->getDescription()).c_str());
1038 lenName = lenName + 2 + strlen((Supports[i]->getName()).c_str());
1039 lenDescription = lenDescription + 2 +
1040 strlen((Supports[i]->getDescription()).c_str());
1043 if(returnedSupport != (SUPPORT *) NULL)
1045 returnedSupportNameChar = new char[lenName];
1046 returnedSupportDescriptionChar = new char[lenDescription];
1048 returnedSupportNameChar = strcpy(returnedSupportNameChar,
1049 "Intersection of ");
1050 returnedSupportDescriptionChar =
1051 strcpy(returnedSupportDescriptionChar,"Intersection of ");
1053 returnedSupportNameChar = strcat(returnedSupportNameChar,
1054 (Supports[0]->getName()).c_str());
1055 returnedSupportDescriptionChar =
1056 strcat(returnedSupportDescriptionChar,
1057 (Supports[0]->getDescription()).c_str());
1059 for(int i = 1;i<size;i++)
1063 returnedSupportNameChar = strcat(returnedSupportNameChar,
1065 returnedSupportDescriptionChar =
1066 strcat(returnedSupportDescriptionChar," and ");
1068 returnedSupportNameChar =
1069 strcat(returnedSupportNameChar,
1070 (Supports[i]->getName()).c_str());
1071 returnedSupportDescriptionChar =
1072 strcat(returnedSupportDescriptionChar,
1073 (Supports[i]->getDescription()).c_str());
1077 returnedSupportNameChar = strcat(returnedSupportNameChar,
1079 returnedSupportNameChar =
1080 strcat(returnedSupportNameChar,
1081 (Supports[i]->getName()).c_str());
1083 returnedSupportDescriptionChar =
1084 strcat(returnedSupportDescriptionChar,", ");
1085 returnedSupportDescriptionChar =
1086 strcat(returnedSupportDescriptionChar,
1087 (Supports[i]->getDescription()).c_str());
1091 returnedSupportName = string(returnedSupportNameChar);
1092 returnedSupport->setName(returnedSupportName);
1094 returnedSupportDescription = string(returnedSupportDescriptionChar);
1095 returnedSupport->setDescription(returnedSupportDescription);
1097 delete [] returnedSupportNameChar;
1098 delete [] returnedSupportDescriptionChar;
1103 return returnedSupport;
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'.
1114 SUPPORT * GMESH::buildSupportOnElementsFromElementList(const list<int>& listOfElt, MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION)
1116 const char* LOC = "GMESH::buildSupportOnElementsFromElementList : ";
1118 SUPPORT * mySupport = new SUPPORT();
1119 mySupport->setMesh((MESH *)this);
1120 mySupport->setName("Boundary");
1121 mySupport->setEntity( entity );
1122 mySupport->fillFromElementList(listOfElt);
1127 // internal helper type
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) {}
1136 //================================================================================
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.)
1144 //================================================================================
1146 void GMESH::createFamilies()
1148 int idFamNode = 0; // identifier for node families
1149 int idFamElement = 0; // identifier for cell, face or edge families
1151 // Main loop on mesh's entities
1152 for (medEntityMesh entity=MED_CELL; entity!=MED_ALL_ENTITIES; ++entity)
1154 int numberofgroups = getNumberOfGroups(entity);
1156 continue; // no groups for this entity
1158 vector< vector<FAMILY*> > whichFamilyInGroup(numberofgroups); // this container is used to update groups at the end
1160 // make myFamilies points to the member corresponding to entity
1161 vector<FAMILY*>* myFamilies;
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;
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();
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
1179 med_int numberOfTypes=0;
1180 const medGeometryElement* geometricTypes = 0;
1181 if ( entity != MED_NODE)
1183 numberOfTypes = getNumberOfTypes(entity);
1184 geometricTypes = getTypes(entity);
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)
1193 int nbCellsOfType = getNumberOfElements(entity,geometricTypes[t]);
1194 for(int n=0; n!=nbCellsOfType; ++n, ++cell)
1195 cell->geometricType=geometricTypes[t];
1198 // 2 - Scan cells in groups and update in tab_cell the container of groups a cell belong to
1200 for (unsigned g=0; g!=myGroups.size(); ++g)
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);
1210 // 3 - Scan the cells vector, genarate family name, and create a map associating the family names
1211 // whith the vector of contained cells
1213 map< string,vector<int> > tab_families;
1214 map< string,vector<int> >::iterator fam;
1215 for(int n=0; n!=numberOfCells; ++n)
1217 ostringstream key; // to generate the name of the family
1219 if(tab_cell[n].groups.empty()) // this cell don't belong to any group
1220 key << "_NONE" << entity;
1222 for(vector<int>::const_iterator it=tab_cell[n].groups.begin(); it!=tab_cell[n].groups.end(); ++it)
1224 string groupName=myGroups[*it]->getName();
1225 if(groupName.empty())
1228 key << "_" << groupName;
1231 tab_families[key.str()].push_back(n+1); // fill the vector of contained cells associated whith the family
1235 // 4 - Scan the family map, create MED Families, check if it already exist.
1237 for( fam=tab_families.begin(); fam!=tab_families.end(); ++fam)
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
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)
1249 int ncell=fam->second[i]-1;
1250 if(tab_cell[ncell].geometricType != geometrictype)
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);
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);
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);
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 ] == ' ' ))
1276 famName = famName.substr( 0, famName.size() - 1 );
1277 foundName = tab_families.find( famName );
1280 tab_families[ famName ]; // add a new name in the table to assure uniqueness
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);
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() );
1307 idFam = -idFamElement;
1311 newFam->setIdentifier(idFam);
1313 // Update links between families and groups
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
1319 newFam->setNumberOfGroups(numberOfGroups);
1320 string * groupNames=new string[numberOfGroups];
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)
1326 whichFamilyInGroup[*it].push_back(newFam);
1327 groupNames[ng]=myGroups[*it]->getName();
1329 newFam->setGroupsNames(groupNames);
1330 delete [] groupNames;
1333 MESSAGE_MED(" MESH::createFamilies() entity " << entity <<
1334 " size " << myFamilies->size());
1336 myFamilies->push_back(newFam);
1339 // delete old families
1340 for (unsigned int i=0;i<myOldFamilies.size();i++)
1341 myOldFamilies[i]->removeReference();
1343 // update references in groups
1344 for (unsigned int i=0;i<myGroups.size();i++)
1346 myGroups[i]->setNumberOfFamilies(whichFamilyInGroup[i].size());
1347 myGroups[i]->setFamilies(whichFamilyInGroup[i]);
1350 // re-scan the cells vector, and fill the family vector with cells.
1351 // creation of support, check if it already exist.
1355 //================================================================================
1357 Create groups from families.
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.
1363 //================================================================================
1365 void GMESH::createGroups()
1367 for (medEntityMesh entity=MED_CELL; entity!=MED_ALL_ENTITIES; ++entity)
1369 // make myFamilies points to the member corresponding to entity
1370 vector<FAMILY*>* myFamilies;
1371 vector<GROUP*>* myGroups;
1375 myFamilies = & _familyCell;
1376 myGroups = & _groupCell;
1379 myFamilies = & _familyFace;
1380 myGroups = & _groupFace;
1383 myFamilies = & _familyEdge;
1384 myGroups = & _groupEdge;
1387 myFamilies = & _familyNode;
1388 myGroups = & _groupNode;
1393 for (unsigned i=0; i< myFamilies->size(); i++)
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);