00001
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
00029
00030
00031 public:
00032
00034 enum {M = SMR::M};
00035
00036
00037
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
00066
00067
00068 private:
00069
00070
00071
00072
00073
00074 public:
00075
00077 typedef typename NodeIteratorSimplex::Face Face;
00078
00079
00080
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
00271 for (int m = 0; m != M+1; ++m) {
00272
00273 if (m != n) {
00274
00275 if (getNeighbor(m) == 0) {
00276 return true;
00277 }
00278 }
00279 }
00280
00281 return false;
00282 }
00283
00285 void
00286 getCentroid(Vertex* centroid) const {
00287
00288
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
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
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
00485 for (typename NodeIteratorSimplex::Iterator i = _nodes.getBeginning();
00486 i != _nodes.getEnd(); ++i) {
00487
00488 (*i)->removeCell(getSelf());
00489
00490 *i = 0;
00491 }
00492
00493 for (typename CellIteratorSimplex::Iterator i = _neighbors.getBeginning();
00494 i != _neighbors.getEnd(); ++i) {
00495
00496 if (*i != 0) {
00497
00498 (*i)->removeNeighbor(getSelf());
00499
00500 *i = 0;
00501 }
00502 }
00503 }
00504
00506
00509 void
00510 removeNeighbor(const CellIterator c) {
00511
00512 typename CellIteratorSimplex::Iterator i = _neighbors.getBeginning();
00513 for (; i != _neighbors.getEnd(); ++i) {
00514
00515 if (*i == c) {
00516
00517 *i = 0;
00518 break;
00519 }
00520 }
00521
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
00541 out << "Id = "<< getIdentifier() << " Vertices = ";
00542
00543 for (int m = 0; m != M+1; ++m) {
00544 assert(_nodes[m] != 0);
00545 out << _nodes[m]->getIdentifier() << " ";
00546 }
00547 out << " Neighbors = ";
00548
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
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
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
00754 assert(false);
00755 return -1;
00756 }
00757
00758
00759
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
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