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
23 #ifndef CONNECTIVITY_HXX
24 #define CONNECTIVITY_HXX
28 #include "MEDMEM_Utilities.hxx"
29 #include "MEDMEM_Exception.hxx"
30 #include "MEDMEM_define.hxx"
31 #include "MEDMEM_CellModel.hxx"
33 #include "InterpKernelHashMap.hxx"
40 class MEDSKYLINEARRAY;
44 MEDMEM_EXPORT std::ostream & operator<<(std::ostream &os, CONNECTIVITY &my);
47 This class deals with all types of connectivity.\n
48 It is a recursive class.
51 /* ------------------------------------------- */
52 class MEDMEM_EXPORT CONNECTIVITY
53 /* ------------------------------------------- */
59 size_t operator()(const std::vector<int>& key) const
62 for (int i=0; i<(int)key.size(); i++)
63 //sum+=key[i]; -- KO for conn of edges of face [1,6,5,2] since 1+6==2+5
64 sum+=key[i]*(i+key.size());
68 // static const size_t bucket_size = 4;
69 // static const size_t min_buckets = 8;
70 // bool operator()(const vector<int>& key1, const vector<int>& key2) const
72 // return ::size_t()(key1) < ::size_t()(key2);
77 typedef INTERP_KERNEL::HashMap<std::vector<int>,int, myHashFn > CONNECTIVITY_HashMap;
79 /* ---------------------- */
81 /* ---------------------- */
84 /*! contains MED_CELL MED_FACE or MED_EDGE */
85 MED_EN::medEntityMesh _entity;
86 /*! contains MED_NODAL or MED_DESCEND */
87 MED_EN::medConnectivity _typeConnectivity;
88 /*! count of differents cells types
91 /*! array of all med_geometric_type used by MESH. */
92 MED_EN::medGeometryElement* _geometricTypes;
94 /*! map indexed by med_geometric_type
95 which contains the different
96 'CellModel' used by MESH. */
98 /*! contains the dimension of the entity */
101 /*! needed by calculateReverseNodalConnectivity */
104 /*! array of size _numberOfTypes+1 which
105 gives for each cell type the first
106 cell number in _nodal or _descending
107 array (depends on _typeConnectivity)
108 To get cells count for one type, we
109 must minus _count[i+1] and _count[i]
110 ( 0 <= i < _numberOfTypes ).
111 Note that _count[_numberOfTypes] returns
112 total cells count + 1 */
115 /*! pointer to an array which stores the nodal connectivity */
116 MEDSKYLINEARRAY* _nodal;
117 /*! pointer to an array which stores
118 the descending connectivity */
119 mutable MEDSKYLINEARRAY* _descending;
120 /*! pointer to an array which stores
121 the reverse nodal connectivity */
122 mutable MEDSKYLINEARRAY* _reverseNodalConnectivity;
123 /*! pointer to an array which stores
124 the reverse descending connectivity */
125 mutable MEDSKYLINEARRAY* _reverseDescendingConnectivity;
126 /*! if face or edge, list of 2 cells or
127 2 faces it belongs to.
128 If 2nd number equals 0, we have a
129 boundary entity. We could use
130 MEDSKYLINEARRAY, but we suppose we have
131 always only 2 (or 1) entities. */
132 MEDSKYLINEARRAY* _neighbourhood;
133 /*! connectivity of sub cell if
134 descendant connectivity is calculated */
135 CONNECTIVITY * _constituent;
136 /*! is descending connectivity computed by
137 calculatePartialDescendingConnectivity() */
138 mutable bool _isDescendingConnectivityPartial;
140 /* -------------------- */
142 /* -------------------- */
145 /*! private method :\n
146 does nothing if already exists, else
147 evaluates _nodal from _descending */
148 void calculateNodalConnectivity() const;
149 /*! private method :\n
150 does nothing if already exists, else
151 evaluates from _nodal */
152 void calculateReverseNodalConnectivity() const;
153 /*! private method :\n
154 does nothing if already exists, else
155 evaluates _descending from _nodal */
156 void calculateDescendingConnectivity() const;
158 void calculatePartialDescendingConnectivity() const;
159 void addToDescendingConnectivity( const std::set<int>& nodes,
160 std::multimap<int,int>& descending,
162 const CONNECTIVITY_HashMap & ) const;
164 /*! private method :\n
165 does nothing if already exists, else
166 evaluates from _descending */
167 // void calculateReverseDescendingConnectivity(CONNECTIVITY *myConnectivity);
169 const int* getReverseNodalConnectivity () const;
170 const int* getReverseNodalConnectivityIndex () const;
171 const int* getReverseDescendingConnectivity () const;
172 const int* getReverseDescendingConnectivityIndex () const;
174 /*! private method :\n
175 does nothing if already exists, else
176 evaluates _neighbourhood from _descending */
177 void calculateNeighbourhood(CONNECTIVITY &myConnectivity);
179 int getIndexOfEndClassicElementInReverseNodal(const int *reverseNodalValue,
180 const int *reverseNodalIndex, int rk) const;
184 friend class MED_MESH_RDONLY_DRIVER;
185 friend class MED_MESH_WRONLY_DRIVER;
188 friend std::ostream & operator<<(std::ostream &os, CONNECTIVITY &connectivity);
190 // in order to fill CONNECTIVITY of MESH
193 CONNECTIVITY (MED_EN::medEntityMesh Entity=MED_EN::MED_CELL);
194 CONNECTIVITY (int numberOfTypes, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL);
195 CONNECTIVITY (const CONNECTIVITY & m);
196 virtual ~CONNECTIVITY ();
198 void setConstituent (CONNECTIVITY * Constituent)
199 throw (MEDEXCEPTION);
200 const CONNECTIVITY* getConstituent (const MED_EN::medEntityMesh Entity) const
201 throw (MEDEXCEPTION);
203 void setGeometricTypes (const MED_EN::medGeometryElement * Types,
204 const MED_EN::medEntityMesh Entity)
205 throw (MEDEXCEPTION);
207 void setCount (const int * Count,
208 const MED_EN::medEntityMesh Entity)
209 throw (MEDEXCEPTION);
211 void setNodal (const int * Connectivity,
212 const MED_EN::medEntityMesh Entity,
213 const MED_EN::medGeometryElement Type,
214 const int * PolyConnectivityIndex=0)
215 throw (MEDEXCEPTION);
217 inline void setNumberOfNodes(int NumberOfNodes);
218 inline int getNumberOfNodes() const;
219 inline int getEntityDimension() const;
221 inline void setEntityDimension(int EntityDimension);
223 inline bool existConnectivity (MED_EN::medConnectivity connectivityType,
224 MED_EN::medEntityMesh Entity) const;
226 virtual void calculateConnectivity (MED_EN::medConnectivity connectivityType,
227 MED_EN::medEntityMesh Entity);
229 virtual void calculateFullDescendingConnectivity(MED_EN::medEntityMesh Entity);
231 virtual void updateFamily (const vector<FAMILY*>& myFamilies);
233 inline MED_EN::medEntityMesh getEntity () const;
235 inline int getNumberOfTypes (MED_EN::medEntityMesh Entity) const;
237 const int * getConnectivityOfAnElement(MED_EN::medConnectivity ConnectivityType,
238 MED_EN::medEntityMesh Entity,
239 int Number, int &lgth) const;
241 inline const MED_EN::medGeometryElement * getGeometricTypes (MED_EN::medEntityMesh Entity) const
242 throw (MEDEXCEPTION);
243 MED_EN::medGeometryElement getElementType (MED_EN::medEntityMesh Entity,
245 inline MED_EN::medGeometryElement getPolyTypeRelativeTo() const;
246 virtual inline const int * getGlobalNumberingIndex (MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION);
248 virtual const int* getConnectivity (MED_EN::medConnectivity ConnectivityType,
249 MED_EN::medEntityMesh Entity,
250 MED_EN::medGeometryElement Type) const;
251 virtual int getConnectivityLength (MED_EN::medConnectivity ConnectivityType,
252 MED_EN::medEntityMesh Entity,
253 MED_EN::medGeometryElement Type) const;
254 virtual const int* getConnectivityIndex (MED_EN::medConnectivity ConnectivityType,
255 MED_EN::medEntityMesh Entity) const;
256 int * getNodesOfPolyhedron(int polyhedronId, int& lgthOfTab) const;
257 int ** getNodesPerFaceOfPolyhedron(int polyhedronId, int& nbOfFaces, int* & nbOfNodesPerFaces) const;
259 const CELLMODEL & getType (MED_EN::medGeometryElement Type) const;
260 const CELLMODEL * getCellsTypes (MED_EN::medEntityMesh Entity) const
261 throw (MEDEXCEPTION);
262 string * getCellTypeNames (MED_EN::medEntityMesh Entity) const
263 throw (MEDEXCEPTION);
265 int getNumberOfNodesInType (MED_EN::medGeometryElement Type) const;
266 int getNumberOfSubCellInType (MED_EN::medGeometryElement Type) const;
267 virtual int getNumberOf (MED_EN::medEntityMesh Entity,
268 MED_EN::medGeometryElement Type) const;
269 virtual const int* getValue (MED_EN::medConnectivity TypeConnectivity,
270 MED_EN::medGeometryElement Type) const;
271 virtual const int* getValueIndex (MED_EN::medConnectivity TypeConnectivity) const;
273 virtual inline const int* getReverseConnectivity (MED_EN::medConnectivity ConnectivityType,
274 MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const
275 throw (MEDEXCEPTION);
276 virtual inline const int* getReverseConnectivityIndex (MED_EN::medConnectivity ConnectivityType,
277 MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const
278 throw (MEDEXCEPTION);
280 const int* getNeighbourhood() const;
281 void invertConnectivityForAFace(int faceId, const int *nodalConnForFace);
282 bool deepCompare(const CONNECTIVITY& other) const;
286 /*----------------------*/
287 /* Methodes Inline */
288 /*----------------------*/
290 /*! Returns the medEntityMesh */
291 //--------------------------------------------------//
292 inline MED_EN::medEntityMesh CONNECTIVITY::getEntity() const
293 //--------------------------------------------------//
298 /*! Returns the number of different %medGeometryElement types
299 existing in the specified entity. \n
300 Note : Not implemented for MED_ALL_ENTITIES. */
301 //-----------------------------------------------------------------------//
302 inline int CONNECTIVITY::getNumberOfTypes(MED_EN::medEntityMesh Entity) const
303 //-----------------------------------------------------------------------//
305 MESSAGE_MED("CONNECTIVITY::getNumberOfTypes : Entity = "<<Entity<<", _entity = "<<_entity);
307 return _numberOfTypes;
308 else if (_constituent!=NULL)
309 return _constituent->getNumberOfTypes(Entity);
310 else if (_constituent == NULL)
312 MESSAGE_MED("CONNECTIVITY::getNumberOfTypes : _constituent == NULL");
315 (const_cast <CONNECTIVITY *> (this))->calculateDescendingConnectivity();
317 catch (MEDEXCEPTION &)
322 SCRUTE_MED(_entityDimension);
324 if (_entityDimension != 2 && _entityDimension != 3) return 0;
328 _constituent->calculateConnectivity(MED_EN::MED_NODAL,Entity);
330 catch (MEDEXCEPTION &)
335 return _constituent->getNumberOfTypes(Entity);
338 return 0; // because it is the right information (no exception needed)!
341 /*! Returns an array of all %medGeometryElement types existing in the mesh
342 for the given %medEntityMesh.
343 Note : Not implemented for MED_ALL_ENTITIES.
344 Throws an exception if Entity is unknown */
345 //------------------------------------------------------------------------------------------//
346 inline const MED_EN::medGeometryElement* CONNECTIVITY::getGeometricTypes(MED_EN::medEntityMesh Entity) const
348 //------------------------------------------------------------------------------------------//
351 return _geometricTypes;
352 else if (_constituent!=NULL)
353 return _constituent->getGeometricTypes(Entity);
355 //throw MEDEXCEPTION("CONNECTIVITY::getGeometricTypes : Entity not defined !");
356 return 0; // idem to supressed getGeometricTypesWithPoly()
359 /*! Returns an array containing the accumulated number of entities sorted by the geometric type.\n
363 In case of a CONNECTIVITY containing 3*MED_TRIA3 et 2*MED_QUAD4 : \n
364 int * count = getGlobalNumberingIndex(MED_CELL)\n
365 count[0] is always set to 1\n
366 count[1] is set to 1+3=4\n
367 count[2] is set to 4+2=6 = total number of cells + 1\n
369 Note : Not implemented for MED_ALL_ENTITIES. \n
370 Note : The geometric type order is given by the typedef enum medGeometryElement.
373 //----------------------------------------------------------------------------------//
374 inline const int * CONNECTIVITY::getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const
376 //----------------------------------------------------------------------------------//
380 else if (_constituent!=NULL)
381 return _constituent->getGlobalNumberingIndex(Entity);
383 throw MEDEXCEPTION("CONNECTIVITY::getGlobalNumberingIndex : Entity not defined !");
386 /*! Returns true if a connectivity exists on elements of type "Entity" */
387 //-----------------------------------------------------------------------------//
388 inline bool CONNECTIVITY::existConnectivity( MED_EN::medConnectivity ConnectivityType,
389 MED_EN::medEntityMesh Entity) const
390 //-----------------------------------------------------------------------------//
392 if (_entity==Entity) {
393 if ((ConnectivityType == MED_EN::MED_NODAL) && (_nodal != (MEDSKYLINEARRAY*)NULL))
395 if ((ConnectivityType==MED_EN::MED_DESCENDING)&(_descending!=(MEDSKYLINEARRAY*)NULL))
397 } else if (_constituent!=NULL)
398 return _constituent->existConnectivity(ConnectivityType,Entity);
403 Returns an array containing CELLMODEL foreach element type present
404 in connectivity for given medEntityMesh (similar as getGeometricTypes).\n
405 Throw an execption if the given entity is not defined or if the array is not defined.
407 //-----------------------------------------------------------------------------//
408 inline const CELLMODEL * CONNECTIVITY::getCellsTypes(MED_EN::medEntityMesh Entity) const
410 //-----------------------------------------------------------------------------//
412 if (Entity == _entity)
416 throw MEDEXCEPTION("CONNECTIVITY::getCellsTypes(medEntityMesh) :"
417 " CELLMODEL array is not defined !");
419 if (_constituent != NULL)
420 return _constituent->getCellsTypes(Entity);
422 throw MEDEXCEPTION("CONNECTIVITY::getCellsTypes(medEntityMesh) : Not found Entity !");
425 Returns an array (it should deleted after use) containing the whole list of
426 CELLMODEL Name foreach element type present in connectivity for given
427 medEntityMesh (similar as getGeometricTypes).\n
428 Throw an execption if the given entity is not defined or if the array is not
432 //-----------------------------------------------------------------------------//
433 inline string * CONNECTIVITY::getCellTypeNames(MED_EN::medEntityMesh Entity) const
435 //-----------------------------------------------------------------------------//
437 if (Entity == _entity)
440 string * stringArray = new string[_numberOfTypes];
442 for (int i=0;i<_numberOfTypes;i++)
443 stringArray[i] = _type[i].getName();
448 throw MEDEXCEPTION("CONNECTIVITY::getCellTypeNames(medEntityMesh) :"
449 " CELLMODEL array is not defined !");
451 if (_constituent != NULL)
452 return _constituent->getCellTypeNames(Entity);
454 throw MEDEXCEPTION("CONNECTIVITY::getCellTypeNames(medEntityMesh) : Not found Entity !");
463 //------------------------------------------------------------------------------------------//
464 inline const int* CONNECTIVITY::getReverseConnectivity( MED_EN::medConnectivity ConnectivityType,
465 MED_EN::medEntityMesh Entity) const
467 //------------------------------------------------------------------------------------------//
471 if (ConnectivityType==MED_EN::MED_NODAL)
472 return getReverseNodalConnectivity();
473 else if (ConnectivityType==MED_EN::MED_DESCENDING)
474 return getReverseDescendingConnectivity();
476 throw MEDEXCEPTION("MESH::getReverseConnectivity : connectivity mode not supported !");
479 if (NULL==_constituent)
480 calculateDescendingConnectivity();
481 return _constituent->getReverseConnectivity(ConnectivityType,Entity);
485 //-----------------------------------------------------------------------------------------------//
486 inline const int* CONNECTIVITY::getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
487 MED_EN::medEntityMesh Entity) const
489 //-----------------------------------------------------------------------------------------------//
493 if (ConnectivityType==MED_EN::MED_NODAL)
494 return getReverseNodalConnectivityIndex();
495 else if (ConnectivityType==MED_EN::MED_DESCENDING)
496 return getReverseDescendingConnectivityIndex();
498 throw MEDEXCEPTION("MESH::getReverseConnectivityIndex : connectivity mode not supported !");
501 if (NULL==_constituent)
502 calculateDescendingConnectivity();
503 return _constituent->getReverseConnectivityIndex(ConnectivityType,Entity);
507 inline void CONNECTIVITY::setNumberOfNodes(int NumberOfNodes)
509 _numberOfNodes=NumberOfNodes;
512 inline int CONNECTIVITY::getNumberOfNodes() const
514 return _numberOfNodes;
517 inline void CONNECTIVITY::setEntityDimension(int EntityDimension)
519 _entityDimension=EntityDimension;
522 int CONNECTIVITY::getEntityDimension() const
524 return _entityDimension;
527 MED_EN::medGeometryElement CONNECTIVITY::getPolyTypeRelativeTo() const
529 if(_entity==MED_EN::MED_CELL && _entityDimension==3)
530 return MED_EN::MED_POLYHEDRA;
531 else if((_entity==MED_EN::MED_CELL && _entityDimension==2) || (_entity==MED_EN::MED_FACE && _entityDimension==2))
532 return MED_EN::MED_POLYGON;
534 throw MEDEXCEPTION("getPolyTypeRelativeTo : ");
540 }//End namespace MEDMEM
542 #endif /* CONNECTIVITY_HXX */