Back to index

salome-med  6.5.0
MEDMEM_Connectivity.hxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #ifndef CONNECTIVITY_HXX
00024 #define CONNECTIVITY_HXX
00025 
00026 #include "MEDMEM.hxx"
00027 
00028 #include "MEDMEM_Utilities.hxx"
00029 #include "MEDMEM_Exception.hxx"
00030 #include "MEDMEM_define.hxx"
00031 #include "MEDMEM_CellModel.hxx"
00032 
00033 #include "InterpKernelHashMap.hxx"
00034 
00035 #include <vector>
00036 #include <set>
00037 #include <map>
00038 
00039 namespace MEDMEM {
00040   class MEDSKYLINEARRAY;
00041   class FAMILY;
00042   class GROUP;
00043   class CONNECTIVITY;
00044   MEDMEM_EXPORT std::ostream & operator<<(std::ostream &os, CONNECTIVITY &my);
00045 
00051 /* ------------------------------------------- */
00052 class MEDMEM_EXPORT CONNECTIVITY
00053 /* ------------------------------------------- */
00054 {
00055 
00056   class myHashFn
00057   {
00058   public:
00059     size_t operator()(const std::vector<int>& key) const
00060     {
00061       size_t sum=0;
00062       for (int i=0; i<(int)key.size(); i++)
00063         //sum+=key[i]; -- KO for conn of edges of face [1,6,5,2] since 1+6==2+5
00064         sum+=key[i]*(i+key.size());
00065       return sum;
00066     }
00067 // #ifdef WNT
00068 //     static const size_t bucket_size = 4;
00069 //     static const size_t min_buckets = 8;
00070 //     bool operator()(const vector<int>& key1, const vector<int>& key2) const
00071 //     {
00072 //       return ::size_t()(key1) < ::size_t()(key2);
00073 //     }
00074 // #endif
00075   };
00076 
00077   typedef INTERP_KERNEL::HashMap<std::vector<int>,int, myHashFn > CONNECTIVITY_HashMap;
00078 
00079   /* ---------------------- */
00080   /*    Class Attributs     */
00081   /* ---------------------- */
00082 
00083 protected:
00085   MED_EN::medEntityMesh           _entity;
00087   MED_EN::medConnectivity         _typeConnectivity;
00090   int                             _numberOfTypes;
00092   MED_EN::medGeometryElement*     _geometricTypes;
00093 
00097   CELLMODEL *      _type;
00099   int              _entityDimension;
00100 
00102   int              _numberOfNodes;
00103 
00113   int *            _count;
00114 
00116   MEDSKYLINEARRAY* _nodal;
00119   mutable MEDSKYLINEARRAY* _descending;
00122   mutable MEDSKYLINEARRAY* _reverseNodalConnectivity;
00125   mutable MEDSKYLINEARRAY* _reverseDescendingConnectivity;
00132   MEDSKYLINEARRAY* _neighbourhood;
00135   CONNECTIVITY *   _constituent;
00138   mutable bool             _isDescendingConnectivityPartial;
00139 
00140   /* -------------------- */
00141   /*    Class Methods     */
00142   /* -------------------- */
00143 
00144 private:
00148   void calculateNodalConnectivity() const;
00152   void calculateReverseNodalConnectivity() const;
00156   void calculateDescendingConnectivity() const;
00157 
00158   void calculatePartialDescendingConnectivity() const;
00159   void addToDescendingConnectivity( const std::set<int>&    nodes,
00160                                     std::multimap<int,int>& descending,
00161                                     int                     iglobal_cell ,
00162                                     const CONNECTIVITY_HashMap & ) const;
00163         
00167   //  void calculateReverseDescendingConnectivity(CONNECTIVITY *myConnectivity);
00168 
00169   const int*      getReverseNodalConnectivity           () const;
00170   const int*      getReverseNodalConnectivityIndex      () const;
00171   const int*      getReverseDescendingConnectivity      () const;
00172   const int*      getReverseDescendingConnectivityIndex () const;
00173 
00177   void calculateNeighbourhood(CONNECTIVITY &myConnectivity);
00178 
00179   int getIndexOfEndClassicElementInReverseNodal(const int *reverseNodalValue,
00180                                                 const int *reverseNodalIndex, int rk)  const;
00181 
00182 public:
00183 
00184   friend class MED_MESH_RDONLY_DRIVER;
00185   friend class MED_MESH_WRONLY_DRIVER;
00186 
00187 
00188   friend std::ostream & operator<<(std::ostream &os, CONNECTIVITY &connectivity);
00189 
00190   // in order to fill CONNECTIVITY of MESH
00191   friend class GRID;
00192 
00193   CONNECTIVITY  (MED_EN::medEntityMesh Entity=MED_EN::MED_CELL);
00194   CONNECTIVITY  (int numberOfTypes, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL);
00195   CONNECTIVITY  (const CONNECTIVITY & m);
00196   virtual ~CONNECTIVITY ();
00197 
00198   void setConstituent (CONNECTIVITY * Constituent)
00199                                         throw (MEDEXCEPTION);
00200   const CONNECTIVITY* getConstituent (const MED_EN::medEntityMesh Entity) const
00201                                         throw (MEDEXCEPTION);
00202 
00203   void setGeometricTypes (const MED_EN::medGeometryElement * Types,
00204                           const MED_EN::medEntityMesh        Entity)
00205                                         throw (MEDEXCEPTION);
00206 
00207   void setCount (const int *                 Count,
00208                  const MED_EN::medEntityMesh Entity)
00209                                         throw (MEDEXCEPTION);
00210 
00211   void setNodal (const int *                      Connectivity,
00212                  const MED_EN::medEntityMesh      Entity,
00213                  const MED_EN::medGeometryElement Type,
00214                  const int *                      PolyConnectivityIndex=0)
00215                                         throw (MEDEXCEPTION);
00216 
00217   inline void setNumberOfNodes(int NumberOfNodes);
00218   inline int  getNumberOfNodes() const;
00219   inline int  getEntityDimension() const;
00220 
00221   inline void setEntityDimension(int EntityDimension);
00222 
00223   inline bool existConnectivity (MED_EN::medConnectivity connectivityType,
00224                                  MED_EN::medEntityMesh   Entity) const;
00225 
00226   virtual void calculateConnectivity (MED_EN::medConnectivity connectivityType,
00227                                       MED_EN::medEntityMesh   Entity);
00228 
00229   virtual void calculateFullDescendingConnectivity(MED_EN::medEntityMesh Entity);
00230 
00231   virtual void updateFamily (const vector<FAMILY*>& myFamilies);
00232 
00233   inline MED_EN::medEntityMesh  getEntity () const;
00234 
00235   inline int                    getNumberOfTypes (MED_EN::medEntityMesh Entity) const;
00236 
00237   const int *  getConnectivityOfAnElement(MED_EN::medConnectivity ConnectivityType,
00238                                           MED_EN::medEntityMesh Entity,
00239                                           int Number, int &lgth) const;
00240 
00241   inline const MED_EN::medGeometryElement * getGeometricTypes (MED_EN::medEntityMesh Entity) const
00242                                                              throw (MEDEXCEPTION);
00243   MED_EN::medGeometryElement                getElementType    (MED_EN::medEntityMesh Entity,
00244                                                                int Number)           const;
00245   inline MED_EN::medGeometryElement         getPolyTypeRelativeTo() const;
00246   virtual inline const int *                getGlobalNumberingIndex (MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION);
00247 
00248   virtual const int* getConnectivity             (MED_EN::medConnectivity    ConnectivityType,
00249                                                   MED_EN::medEntityMesh      Entity,
00250                                                   MED_EN::medGeometryElement Type) const;
00251   virtual int        getConnectivityLength       (MED_EN::medConnectivity    ConnectivityType,
00252                                                   MED_EN::medEntityMesh      Entity,
00253                                                   MED_EN::medGeometryElement Type) const;
00254   virtual const int* getConnectivityIndex        (MED_EN::medConnectivity ConnectivityType,
00255                                                   MED_EN::medEntityMesh   Entity) const;
00256   int *              getNodesOfPolyhedron(int polyhedronId, int& lgthOfTab) const;
00257   int **             getNodesPerFaceOfPolyhedron(int polyhedronId, int& nbOfFaces, int* & nbOfNodesPerFaces) const;
00258 
00259   const CELLMODEL &  getType                  (MED_EN::medGeometryElement Type) const;
00260   const CELLMODEL *  getCellsTypes            (MED_EN::medEntityMesh Entity)    const
00261                                             throw (MEDEXCEPTION);
00262   string *           getCellTypeNames         (MED_EN::medEntityMesh Entity) const
00263                                             throw (MEDEXCEPTION);
00264 
00265   int                getNumberOfNodesInType   (MED_EN::medGeometryElement Type) const;
00266   int                getNumberOfSubCellInType (MED_EN::medGeometryElement Type) const;
00267   virtual int        getNumberOf              (MED_EN::medEntityMesh      Entity,
00268                                                MED_EN::medGeometryElement Type) const;
00269   virtual const int* getValue                 (MED_EN::medConnectivity    TypeConnectivity,
00270                                                MED_EN::medGeometryElement Type) const;
00271   virtual const int* getValueIndex            (MED_EN::medConnectivity    TypeConnectivity) const;
00272 
00273   virtual inline const int* getReverseConnectivity (MED_EN::medConnectivity ConnectivityType,
00274                                                     MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const
00275                                             throw (MEDEXCEPTION);
00276   virtual inline const int* getReverseConnectivityIndex (MED_EN::medConnectivity ConnectivityType,
00277                                                          MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const
00278                                             throw (MEDEXCEPTION);
00279 
00280   const int*         getNeighbourhood() const;
00281   void invertConnectivityForAFace(int faceId, const int *nodalConnForFace);
00282   bool deepCompare(const CONNECTIVITY& other) const;
00283 
00284 
00285 };
00286 /*----------------------*/
00287 /* Methodes Inline      */
00288 /*----------------------*/
00289 
00291 //--------------------------------------------------//
00292 inline MED_EN::medEntityMesh CONNECTIVITY::getEntity() const
00293 //--------------------------------------------------//
00294 {
00295         return _entity;
00296 }
00297 
00301 //-----------------------------------------------------------------------//
00302 inline int CONNECTIVITY::getNumberOfTypes(MED_EN::medEntityMesh Entity) const
00303 //-----------------------------------------------------------------------//
00304 {
00305   MESSAGE_MED("CONNECTIVITY::getNumberOfTypes : Entity = "<<Entity<<", _entity = "<<_entity);
00306   if (_entity==Entity)
00307     return _numberOfTypes;
00308   else if (_constituent!=NULL)
00309     return _constituent->getNumberOfTypes(Entity);
00310   else if (_constituent == NULL)
00311     {
00312       MESSAGE_MED("CONNECTIVITY::getNumberOfTypes : _constituent == NULL");
00313       try
00314         {
00315           (const_cast <CONNECTIVITY *> (this))->calculateDescendingConnectivity();
00316         }
00317       catch (MEDEXCEPTION &)
00318         {
00319           return 0 ;
00320         }
00321 
00322       SCRUTE_MED(_entityDimension);
00323 
00324       if (_entityDimension != 2 && _entityDimension != 3) return 0;
00325 
00326       try
00327         {
00328           _constituent->calculateConnectivity(MED_EN::MED_NODAL,Entity);
00329         }
00330       catch (MEDEXCEPTION &)
00331         {
00332           return 0 ;
00333         }
00334 
00335       return _constituent->getNumberOfTypes(Entity);
00336     }
00337   else
00338         return 0; // because it is the right information (no exception needed)!
00339 }
00340 
00345 //------------------------------------------------------------------------------------------//
00346 inline const MED_EN::medGeometryElement* CONNECTIVITY::getGeometricTypes(MED_EN::medEntityMesh Entity) const
00347                                                 throw (MEDEXCEPTION)
00348 //------------------------------------------------------------------------------------------//
00349 {
00350   if (_entity==Entity)
00351     return _geometricTypes;
00352   else if (_constituent!=NULL)
00353     return _constituent->getGeometricTypes(Entity);
00354   else
00355     //throw MEDEXCEPTION("CONNECTIVITY::getGeometricTypes : Entity not defined !");
00356     return 0; // idem to supressed getGeometricTypesWithPoly()
00357 }
00358 
00373 //----------------------------------------------------------------------------------//
00374 inline const int * CONNECTIVITY::getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const
00375                                                 throw (MEDEXCEPTION)
00376 //----------------------------------------------------------------------------------//
00377 {
00378   if (_entity==Entity)
00379         return _count;
00380   else if (_constituent!=NULL)
00381         return _constituent->getGlobalNumberingIndex(Entity);
00382   else
00383         throw MEDEXCEPTION("CONNECTIVITY::getGlobalNumberingIndex : Entity not defined !");
00384 }
00385 
00387 //-----------------------------------------------------------------------------//
00388 inline bool CONNECTIVITY::existConnectivity( MED_EN::medConnectivity ConnectivityType,
00389                                              MED_EN::medEntityMesh Entity) const
00390 //-----------------------------------------------------------------------------//
00391 {
00392   if (_entity==Entity) {
00393     if ((ConnectivityType == MED_EN::MED_NODAL) && (_nodal != (MEDSKYLINEARRAY*)NULL))
00394       return true;
00395     if ((ConnectivityType==MED_EN::MED_DESCENDING)&(_descending!=(MEDSKYLINEARRAY*)NULL))
00396       return true;
00397   } else if (_constituent!=NULL)
00398     return _constituent->existConnectivity(ConnectivityType,Entity);
00399   return false;
00400 }
00401 
00407 //-----------------------------------------------------------------------------//
00408 inline const CELLMODEL * CONNECTIVITY::getCellsTypes(MED_EN::medEntityMesh Entity) const
00409                                                 throw (MEDEXCEPTION)
00410 //-----------------------------------------------------------------------------//
00411 {
00412   if (Entity == _entity)
00413     if (_type!=NULL)
00414       return _type;
00415     else
00416       throw MEDEXCEPTION("CONNECTIVITY::getCellsTypes(medEntityMesh) :"
00417                          " CELLMODEL array is not defined !");
00418   else
00419     if (_constituent != NULL)
00420       return _constituent->getCellsTypes(Entity);
00421     else
00422       throw MEDEXCEPTION("CONNECTIVITY::getCellsTypes(medEntityMesh) : Not found Entity !");
00423 }
00432 //-----------------------------------------------------------------------------//
00433 inline string * CONNECTIVITY::getCellTypeNames(MED_EN::medEntityMesh Entity) const
00434                                                 throw (MEDEXCEPTION)
00435 //-----------------------------------------------------------------------------//
00436 {
00437   if (Entity == _entity)
00438     if (_type!=NULL)
00439       {
00440         string * stringArray = new string[_numberOfTypes];
00441 
00442         for (int i=0;i<_numberOfTypes;i++)
00443           stringArray[i] = _type[i].getName();
00444 
00445         return stringArray;
00446       }
00447     else
00448       throw MEDEXCEPTION("CONNECTIVITY::getCellTypeNames(medEntityMesh) :"
00449                          " CELLMODEL array is not defined !");
00450   else
00451     if (_constituent != NULL)
00452       return _constituent->getCellTypeNames(Entity);
00453     else
00454       throw MEDEXCEPTION("CONNECTIVITY::getCellTypeNames(medEntityMesh) : Not found Entity !");
00455 }
00456 
00457 
00458 
00459 
00460 
00461 
00463 //------------------------------------------------------------------------------------------//
00464 inline const int* CONNECTIVITY::getReverseConnectivity( MED_EN::medConnectivity ConnectivityType,
00465                                                         MED_EN::medEntityMesh   Entity) const
00466                                                             throw (MEDEXCEPTION)
00467 //------------------------------------------------------------------------------------------//
00468 {
00469   if(_entity==Entity)
00470   {
00471     if (ConnectivityType==MED_EN::MED_NODAL)
00472       return getReverseNodalConnectivity();
00473     else if (ConnectivityType==MED_EN::MED_DESCENDING)
00474       return getReverseDescendingConnectivity();
00475     else
00476       throw MEDEXCEPTION("MESH::getReverseConnectivity : connectivity mode not supported !");
00477   }
00478   // other entity :
00479   if (NULL==_constituent)
00480     calculateDescendingConnectivity();
00481   return _constituent->getReverseConnectivity(ConnectivityType,Entity);
00482 }
00483 
00485 //-----------------------------------------------------------------------------------------------//
00486 inline const int* CONNECTIVITY::getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
00487                                                             MED_EN::medEntityMesh   Entity) const
00488                                                                 throw (MEDEXCEPTION)
00489 //-----------------------------------------------------------------------------------------------//
00490 {
00491   if(_entity==Entity)
00492   {
00493     if (ConnectivityType==MED_EN::MED_NODAL)
00494       return getReverseNodalConnectivityIndex();
00495     else if (ConnectivityType==MED_EN::MED_DESCENDING)
00496       return getReverseDescendingConnectivityIndex();
00497     else
00498       throw MEDEXCEPTION("MESH::getReverseConnectivityIndex : connectivity mode not supported !");
00499   }
00500   // other entity :
00501   if (NULL==_constituent)
00502     calculateDescendingConnectivity();
00503   return _constituent->getReverseConnectivityIndex(ConnectivityType,Entity);
00504 }
00505 
00506 
00507 inline void CONNECTIVITY::setNumberOfNodes(int NumberOfNodes)
00508 {
00509   _numberOfNodes=NumberOfNodes;
00510 }
00511 
00512 inline int CONNECTIVITY::getNumberOfNodes() const
00513 {
00514   return _numberOfNodes;
00515 }
00516 
00517 inline void CONNECTIVITY::setEntityDimension(int EntityDimension)
00518 {
00519   _entityDimension=EntityDimension;
00520 }
00521 
00522 int CONNECTIVITY::getEntityDimension() const
00523 {
00524   return _entityDimension;
00525 }
00526 
00527 MED_EN::medGeometryElement CONNECTIVITY::getPolyTypeRelativeTo() const
00528 {
00529   if(_entity==MED_EN::MED_CELL && _entityDimension==3)
00530     return MED_EN::MED_POLYHEDRA;
00531   else if((_entity==MED_EN::MED_CELL && _entityDimension==2) || (_entity==MED_EN::MED_FACE && _entityDimension==2))
00532     return MED_EN::MED_POLYGON;
00533   else
00534     throw MEDEXCEPTION("getPolyTypeRelativeTo : ");
00535 }
00536 
00537 
00538 
00539 
00540 }//End namespace MEDMEM
00541 
00542 #endif /* CONNECTIVITY_HXX */
00543 
00544