vtf-logo

SmrCell.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00008 #if !defined(__geom_mesh_simplicial_SmrCell_h__)
00009 #define __geom_mesh_simplicial_SmrCell_h__
00010 
00011 #if defined(DEBUG_geom) && !defined(DEBUG_SmrCell)
00012 #define DEBUG_SmrCell
00013 #endif
00014 
00015 #include "../../defs.h"
00016 
00017 #include "../simplex/topology.h"
00018 
00019 BEGIN_NAMESPACE_GEOM
00020 
00022 
00025 template<class SMR>
00026 class SmrCell {
00027   //
00028   // Enumerations.
00029   //
00030 
00031 public:
00032 
00034   enum {M = SMR::M};
00035 
00036   //
00037   // Public types.
00038   //
00039 
00040 public:
00041 
00043   typedef SMR Mesh;
00044 
00046   typedef typename Mesh::CellIterator CellIterator;
00048   typedef typename Mesh::CellConstIterator CellConstIterator;
00049 
00051   typedef typename Mesh::NodeIterator NodeIterator;
00053   typedef typename Mesh::NodeConstIterator NodeConstIterator;
00055   typedef typename Mesh::Vertex Vertex;
00057   typedef typename Mesh::Number Number;
00058 
00060   typedef Simplex<M,NodeIterator> NodeIteratorSimplex;
00062   typedef Simplex<M,CellIterator> CellIteratorSimplex;
00063 
00064   //
00065   // Private types.
00066   //
00067 
00068 private:
00069 
00070   //
00071   // Public types.
00072   //
00073 
00074 public:
00075 
00077   typedef typename NodeIteratorSimplex::Face Face;
00078       
00079   //
00080   // Data
00081   //
00082 
00083 private:
00084   
00086   NodeIteratorSimplex _nodes;
00088   CellIteratorSimplex _neighbors;
00090   mutable int _identifier;
00092   CellIterator _self;
00093 
00094 public:
00095 
00096   //--------------------------------------------------------------------------
00099 
00101   SmrCell() :
00102     _nodes(),
00103     _neighbors(),
00104     _identifier(-1),
00105     _self(0) {
00106     _nodes.setEach(NodeIterator(0));
00107     _neighbors.setEach(CellIterator(0));
00108   }
00109 
00111   SmrCell(const NodeIterator v0, const NodeIterator v1, 
00112           const CellIterator c0 = CellIterator(0), 
00113           const CellIterator c1 = CellIterator(0),
00114           const int identifier = -1) :
00115     _nodes(v0, v1),
00116     _neighbors(c0, c1),
00117     _identifier(identifier),
00118     _self(0) {
00119     LOKI_STATIC_CHECK(M == 1, TheSimplexDimensionMustBe1);
00120   }
00121   
00123   SmrCell(const NodeIterator v0, const NodeIterator v1, 
00124           const NodeIterator v2, 
00125           const CellIterator c0 = CellIterator(0), 
00126           const CellIterator c1 = CellIterator(0), 
00127           const CellIterator c2 = CellIterator(0),
00128           const int identifier = -1) :
00129     _nodes(v0, v1, v2),
00130     _neighbors(c0, c1, c2),
00131     _identifier(identifier),
00132     _self(0) {
00133     LOKI_STATIC_CHECK(M == 2, TheSimplexDimensionMustBe2);
00134   }
00135   
00137   SmrCell(const NodeIterator v0, const NodeIterator v1, 
00138           const NodeIterator v2, const NodeIterator v3, 
00139           const CellIterator c0 = CellIterator(0), 
00140           const CellIterator c1 = CellIterator(0), 
00141           const CellIterator c2 = CellIterator(0), 
00142           const CellIterator c3 = CellIterator(0),
00143           const int identifier = -1) :
00144     _nodes(v0, v1, v2, v3),
00145     _neighbors(c0, c1, c2, c3),
00146     _identifier(identifier),
00147     _self(0) {
00148     LOKI_STATIC_CHECK(M == 3, TheSimplexDimensionMustBe3);
00149   }
00150   
00152   SmrCell(const SmrCell& other) :
00153     _nodes(other._nodes),
00154     _neighbors(other._neighbors),
00155     _identifier(other._identifier),
00156     _self(other._self)
00157   {}
00158 
00160   ~SmrCell()
00161   {}
00162 
00164   //--------------------------------------------------------------------------
00167       
00169   SmrCell& 
00170   operator=(const SmrCell& other) {
00171     if (&other != this) {
00172       _nodes = other._nodes;
00173       _neighbors = other._neighbors;
00174       _identifier = other._identifier;
00175       _self = other._self;
00176     }
00177     return *this;
00178   }
00179 
00181   //--------------------------------------------------------------------------
00184 
00186 
00190   int
00191   getIdentifier() const {
00192     return _identifier;
00193   }
00194 
00196   CellConstIterator
00197   getSelf() const {
00198     return _self;
00199   }
00200 
00202   NodeConstIterator
00203   getNode(const int m) const {
00204     return _nodes[m];
00205   }
00206 
00208   const NodeIteratorSimplex&
00209   getNodes() const {
00210     return _nodes;
00211   }
00212 
00214   int
00215   getIndex(NodeConstIterator node) const {
00216     return _nodes.getVertexIndex(node);
00217   }
00218 
00220   int
00221   getIndex(NodeIterator node) const {
00222     return _nodes.getVertexIndex(node);
00223   }
00224 
00226 
00229   int
00230   getIndex(const Face& f) const {
00231     for (int m = 0; m != M + 1; ++m) {
00232       if (! f.hasVertex(_nodes[m])) {
00233         return m;
00234       }
00235     }
00236     assert(false);
00237     return -1;
00238   }
00239 
00241   bool
00242   hasNode(NodeConstIterator node) const {
00243     return _nodes.hasVertex(node);
00244   }
00245 
00247 
00250   bool
00251   hasNode(NodeConstIterator node, int* m) const {
00252     return _nodes.hasVertex(node, m);
00253   }
00254 
00256   bool
00257   hasIncidentBoundaryFace(NodeConstIterator node) const {
00258 #ifdef DEBUG_SmrCell
00259     assert(hasNode(node));
00260 #endif
00261     return hasIncidentBoundaryFace(getIndex(node));
00262   }
00263 
00265   bool
00266   hasIncidentBoundaryFace(const int n) const {
00267 #ifdef DEBUG_SmrCell
00268     assert(0 <= n && n < M + 1);
00269 #endif    
00270     // For each face incident to the node.
00271     for (int m = 0; m != M+1; ++m) {
00272       // Exclude the face opposite this node.
00273       if (m != n) {
00274         // If the face is on the boundary.
00275         if (getNeighbor(m) == 0) {
00276           return true;
00277         }
00278       }
00279     }
00280     // We did not encounter any incident boundary faces.
00281     return false;
00282   }
00283 
00285   void
00286   getCentroid(Vertex* centroid) const {
00287     // CONTINUE: This is the arithmetic mean.  Look up the formula for 
00288     // the centroid.
00289     *centroid = _nodes[0]->getVertex();
00290     for (int m = 1; m != M+1; ++m) {
00291       *centroid += _nodes[m]->getVertex();
00292     }
00293     *centroid /= (M + 1);
00294   }
00295 
00297   CellConstIterator
00298   getNeighbor(const int m) const {
00299     return _neighbors[m];
00300   }
00301 
00303   bool
00304   isFaceOnBoundary(const int m) const {
00305     return getNeighbor(m) == CellConstIterator(0);
00306   }
00307 
00309   int
00310   getNumberOfNeighbors() const {
00311     return M + 1 - int(std::count(_neighbors.begin(), _neighbors.end(), 
00312                                   CellConstIterator(0)));
00313   }
00314 
00316   int
00317   getIndex(CellConstIterator c) const {
00318     return _neighbors.getVertexIndex(c);
00319   }
00320 
00322   bool
00323   hasNeighbor(CellConstIterator c) const {
00324     return _neighbors.hasVertex(c);
00325   }
00326 
00328 
00331   bool
00332   hasNeighbor(CellConstIterator c, int* m) const {
00333     return _neighbors.hasVertex(c, m);
00334   }
00335 
00337   int
00338   getMirrorIndex(const int m) const {
00339     if (_neighbors[m] == 0) {
00340       return -1;
00341     }
00342     return _neighbors[m]->getIndex(_self);
00343   }
00344 
00346 
00349   Number
00350   computeMinimumEdgeLength(int* a, int* b) const {
00351     Number x = std::numeric_limits<Number>::max();
00352     Number d;
00353     int j;
00354     // For each edge.
00355     for (int i = 0; i != M; ++i) {
00356       for (j = i+1; j != M + 1; ++j) {
00357         d = geom::computeDistance(_nodes[i]->getVertex(), 
00358                                   _nodes[j]->getVertex());
00359         if (d < x) {
00360           x = d;
00361           *a = i;
00362           *b = j;
00363         }
00364       }
00365     }
00366     return x;
00367   }
00368   
00370 
00373   Number
00374   computeMaximumEdgeLength(int* a, int* b) const {
00375     Number x = 0;
00376     Number d;
00377     int j;
00378     // For each edge.
00379     for (int i = 0; i != M; ++i) {
00380       for (j = i+1; j != M + 1; ++j) {
00381         d = geom::computeDistance(_nodes[i]->getVertex(), 
00382                                   _nodes[j]->getVertex());
00383         if (d > x) {
00384           x = d;
00385           *a = i;
00386           *b = j;
00387         }
00388       }
00389     }
00390     return x;
00391   }
00392   
00394   Number
00395   computeMinimumEdgeLength() const {
00396     int a, b;
00397     return computeMinimumEdgeLength(&a, &b);
00398   }
00399   
00401   Number
00402   computeMaximumEdgeLength() const {
00403     int a, b;
00404     return computeMaximumEdgeLength(&a, &b);
00405   }
00406 
00408   void
00409   getSimplex(Simplex<M,Vertex>* simplex) {
00410     for (int m = 0; m != M + 1; ++m) {
00411       (*simplex)[m] = getNode(m)->getVertex();
00412     }
00413   }
00414  
00416   //--------------------------------------------------------------------------
00419 
00421 
00425   void
00426   setIdentifier(const int identifier) const { 
00427     _identifier = identifier;
00428   }
00429 
00431   CellIterator
00432   getSelf() {
00433     return _self;
00434   }
00435 
00437   void
00438   setSelf(const CellIterator self) {
00439     _self = self;
00440   }
00441 
00443   NodeIterator
00444   getNode(const int m) {
00445     return _nodes[m];
00446   }
00447 
00449   void
00450   setNode(const int m, const NodeIterator node) {
00451     _nodes[m] = node;
00452   }
00453 
00455   CellIterator
00456   getNeighbor(const int m) {
00457     return _neighbors[m];
00458   }
00459 
00461   void
00462   setNeighbor(const int m, const CellIterator c) {
00463     _neighbors[m] = c;
00464   }
00465 
00467   NodeIterator
00468   getMirrorVertex(const int m) {
00469     if (_neighbors[m] == 0) {
00470       return NodeIterator(0);
00471     }
00472     return _neighbors[m]->getNode(getMirrorIndex(m));
00473   }
00474 
00476   void
00477   getFace(const int m, Face* f) {
00478     _nodes.getFace(m, f);
00479   }
00480 
00482   void
00483   unlink() {
00484     // For each vertex.
00485     for (typename NodeIteratorSimplex::Iterator i = _nodes.getBeginning();
00486           i != _nodes.getEnd(); ++i) {
00487       // Remove the vertices' link to this cell.
00488       (*i)->removeCell(getSelf());
00489       // Remove the link to the vertex.
00490       *i = 0;
00491     }
00492     // For each neigbor.
00493     for (typename CellIteratorSimplex::Iterator i = _neighbors.getBeginning();
00494           i != _neighbors.getEnd(); ++i) {
00495       // If there is a neighbor.
00496       if (*i != 0) {
00497         // Remove the neighbor's link to this cell.
00498         (*i)->removeNeighbor(getSelf());
00499         // Remove the link to the neighbor.
00500         *i = 0;
00501       }
00502     }
00503   }
00504 
00506 
00509   void
00510   removeNeighbor(const CellIterator c) {
00511     // For each neigbor.
00512     typename CellIteratorSimplex::Iterator i = _neighbors.getBeginning();
00513     for (; i != _neighbors.getEnd(); ++i) {
00514       // If this is the specified neighbor.
00515       if (*i == c) {
00516         // Remove the link to the neighbor.
00517         *i = 0;
00518         break;
00519       }
00520     }
00521     // The specified cell must be a neighbor.
00522     assert(i != _neighbors.getEnd());
00523   }
00524 
00526   void
00527   negate() {
00528     _nodes.negate();
00529     _neighbors.negate();
00530   }
00531 
00533   //--------------------------------------------------------------------------
00536 
00538   void
00539   put(std::ostream& out) const {
00540     // Write the simplex identifier.
00541     out << "Id = "<< getIdentifier() << " Vertices = ";
00542     // Write the incident nodes.
00543     for (int m = 0; m != M+1; ++m) {
00544       assert(_nodes[m] != 0);
00545       out << _nodes[m]->getIdentifier() << " ";
00546     }
00547     out << " Neighbors = ";
00548     // Write the neighbors.
00549     for (int m = 0; m != M+1; ++m) {
00550       if (_neighbors[m] != 0) {
00551         out << _neighbors[m]->getIdentifier() << " ";
00552       }
00553       else {
00554         out << "-1 ";
00555       }
00556     }
00557     out << "\n";
00558   }
00559 
00561 };
00562 
00563 
00565 
00570 template<class SMR>
00571 bool
00572 doesCellHaveIncidentFaceOnBoundary(const typename SMR::CellConstIterator& c, 
00573                                    int i, int j);
00574 
00575 
00577 
00586 template<class SMR>
00587 bool
00588 isOnBoundary(const typename SMR::CellConstIterator& c, int i, int j);
00589 
00590 
00592 
00601 template<class SMR>
00602 inline
00603 bool
00604 isOnBoundary(const typename SMR::Edge& edge) {
00605   return isOnBoundary<SMR>(edge.first, edge.second, edge.third);
00606 }
00607 
00608 
00610 
00613 template<class SMR>
00614 inline
00615 bool
00616 hasFace(typename SMR::CellConstIterator cell, 
00617         typename SMR::Cell::Face& face,
00618         int* faceIndex) {
00619   return hasFace(cell->getNodes(), face, faceIndex);
00620 }
00621 
00622 
00624 
00627 template<class SMR>
00628 inline
00629 bool
00630 hasFace(typename SMR::CellConstIterator cell, 
00631         typename SMR::Cell::Face& face) {
00632   int faceIndex;
00633   return hasFace<SMR>(cell, face, &faceIndex);
00634 }
00635 
00636 
00638 
00643 template<class SMR>
00644 inline
00645 bool
00646 hasFace(typename SMR::CellConstIterator cell, 
00647         typename SMR::NodeConstIterator a,
00648         typename SMR::NodeConstIterator b,
00649         typename SMR::NodeConstIterator c,
00650         int* faceIndex) {
00651   return hasFace(cell->getNodes(), a, b, c, faceIndex);
00652 }
00653 
00654 
00656 
00661 template<class SMR>
00662 inline
00663 bool
00664 hasFace(typename SMR::CellConstIterator cell, 
00665         typename SMR::NodeConstIterator a,
00666         typename SMR::NodeConstIterator b,
00667         typename SMR::NodeConstIterator c) {
00668   int dummy;
00669   return hasFace<SMR>(cell, a, b, c, &dummy);
00670 }
00671 
00672 
00674 
00679 template<class SMR>
00680 inline
00681 bool
00682 hasFace(typename SMR::CellIterator cell, 
00683         typename SMR::NodeIterator a,
00684         typename SMR::NodeIterator b,
00685         typename SMR::NodeIterator c,
00686         int* faceIndex) {
00687   return hasFace(cell->getNodes(), a, b, c, faceIndex);
00688 }
00689 
00690 
00692 
00697 template<class SMR>
00698 inline
00699 bool
00700 hasFace(typename SMR::CellIterator cell, 
00701         typename SMR::NodeIterator a,
00702         typename SMR::NodeIterator b,
00703         typename SMR::NodeIterator c) {
00704   int dummy;
00705   return hasFace<SMR>(cell, a, b, c, &dummy);
00706 }
00707 
00708 
00709 // Below are the even and odd permutations of the nodes.  We use even 
00710 // permutations to get the next node and odd permutations to get the 
00711 // previous node.
00712 //
00713 // Even Odd
00714 // 0123 0132
00715 // 0231 0213
00716 // 0312 0321
00717 // 1032 1032
00718 // 1203 1230
00719 // 1320 1302
00720 // 2013 2031
00721 // 2130 2103
00722 // 2301 2310
00723 // 3021 3012
00724 // 3102 3120
00725 // 3210 3201
00726 
00727 
00728 // CONTINUE: Make this a singleton.  Static data may be a bad idea.
00729 // Also, I should move this to Simplex.
00731 inline
00732 int
00733 getNextNodeIndex(const int i, const int j) {
00734   const int Size = 12;
00735   static int even[Size][3] = 
00736     {{0,1,2},
00737      {0,2,3},
00738      {0,3,1},
00739      {1,0,3},
00740      {1,2,0},
00741      {1,3,2},
00742      {2,0,1},
00743      {2,1,3},
00744      {2,3,0},
00745      {3,0,2},
00746      {3,1,0},
00747      {3,2,1}};
00748   for (int n = 0; n != Size; ++n) {
00749     if (even[n][0] == i && even[n][1] == j) {
00750       return even[n][2];
00751     }
00752   }
00753   // Here we check that i and j have sensible values.
00754   assert(false);
00755   return -1;
00756 }
00757 
00758 
00759 // CONTINUE: Make this a singleton.  Static data may be a bad idea.
00761 inline
00762 int
00763 getPreviousNodeIndex(const int i, const int j) {
00764   const int Size = 12;
00765   static int odd[Size][3] = 
00766     {{0,1,3},
00767      {0,2,1},
00768      {0,3,2},
00769      {1,0,2},
00770      {1,2,3},
00771      {1,3,0},
00772      {2,0,3},
00773      {2,1,0},
00774      {2,3,1},
00775      {3,0,1},
00776      {3,1,2},
00777      {3,2,0}};
00778   for (int n = 0; n != Size; ++n) {
00779     if (odd[n][0] == i && odd[n][1] == j) {
00780       return odd[n][2];
00781     }
00782   }
00783   // Here we check that i and j have sensible values.
00784   assert(false);
00785   return -1;
00786 }
00787 
00788 
00790 template <typename SMR>
00791 inline
00792 int
00793 getNextNodeIndex(const typename SMR::CellConstIterator cell, 
00794                  const typename SMR::NodeConstIterator a, 
00795                  const typename SMR::NodeConstIterator b) {
00796   assert(cell->hasNode(a) && cell->hasNode(b));
00797   return getNextNodeIndex(cell->getIndex(a), cell->getIndex(b));
00798 }
00799 
00800 
00802 template <typename SMR>
00803 inline
00804 int
00805 getPreviousNodeIndex(const typename SMR::CellConstIterator cell, 
00806                      const typename SMR::NodeConstIterator a, 
00807                      const typename SMR::NodeConstIterator b) {
00808   assert(cell->hasNode(a) && cell->hasNode(b));
00809   return getPreviousNodeIndex(cell->getIndex(a), cell->getIndex(b));
00810 }
00811 
00812 
00813 END_NAMESPACE_GEOM
00814 
00815 #define __geom_mesh_simplicial_SmrCell_ipp__
00816 #include "SmrCell.ipp"
00817 #undef __geom_mesh_simplicial_SmrCell_ipp__
00818 
00819 #endif

Generated on Fri Aug 24 12:55:59 2007 for Computational Geometry Package by  doxygen 1.4.7