|
AFEPack
|
00001 00011 #ifndef _HGeometry_h_ 00012 #define _HGeometry_h_ 00013 00014 #include <iostream> 00015 #include <fstream> 00016 #include <string> 00017 #include <vector> 00018 #include <list> 00019 #include <iterator> 00020 #include <algorithm> 00021 00022 #include <base/exceptions.h> 00023 00024 #include "DerefIterator.h" 00025 #include "Geometry.h" 00026 #include "TemplateElement.h" 00027 00028 template <int DIM, int DOW> class HGeometry; 00029 template <int DOW> class HGeometry<0,DOW>; 00030 template <int DOW> class HGeometry<1,DOW>; 00031 template <int DOW> class HGeometry<2,DOW>; 00032 template <int DOW> class HGeometry<3,DOW>; 00033 template <int DIM, int DOW> class HGeometryTree; 00034 template <int DIM, int DOW> class RegularMesh; 00035 template <int DIM, int DOW> class IrregularMesh; 00036 template <int DIM, int DOW> class HElement; 00037 00038 template <int DIM, int DOW> class ElementIterator; 00039 template <int DIM, int DOW> class RootFirstElementIterator; 00040 template <int DIM, int DOW> class ActiveElementIterator; 00041 template <int DIM, int DOW> class IrregularMeshPair; 00042 template <int DIM, int DOW> class ActiveElementPairIterator; 00043 00044 template <int DIM, int DOW> std::ostream& operator<<(std::ostream&, const HGeometry<DIM,DOW>&); 00045 template <int DIM, int DOW> std::ostream& operator<<(std::ostream&, const HElement<DIM, DOW>&); 00046 00047 template <int DIM, int DOW> std::ostream& operator<<(std::ostream&, IrregularMesh<DIM, DOW>&); 00048 template <int DOW> std::ostream& operator<<(std::ostream&, const HGeometry<0,DOW>&); 00049 00050 template <int DIM, int DOW> bool operator==(const ElementIterator<DIM, DOW>&, 00051 const ElementIterator<DIM, DOW>&); 00052 template <int DIM, int DOW> bool operator!=(const ElementIterator<DIM, DOW>&, 00053 const ElementIterator<DIM, DOW>&); 00054 template <int DIM, int DOW> bool operator==(const ElementIterator<DIM, DOW>&, 00055 ElementIterator<DIM, DOW>&); 00056 template <int DIM, int DOW> bool operator!=(const ElementIterator<DIM, DOW>&, 00057 ElementIterator<DIM, DOW>&); 00058 00059 template <int DIM, int DOW> bool operator==(const ActiveElementPairIterator<DIM, DOW>&, 00060 const ActiveElementPairIterator<DIM, DOW>&); 00061 template <int DIM, int DOW> bool operator!=(const ActiveElementPairIterator<DIM, DOW>&, 00062 const ActiveElementPairIterator<DIM, DOW>&); 00063 template <int DIM, int DOW> bool operator==(const ActiveElementPairIterator<DIM, DOW>&, 00064 ActiveElementPairIterator<DIM, DOW>&); 00065 template <int DIM, int DOW> bool operator!=(const ActiveElementPairIterator<DIM, DOW>&, 00066 ActiveElementPairIterator<DIM, DOW>&); 00067 00068 template <int DIM> 00069 struct HGeometryInfo { 00070 enum { 00071 dimension = DIM, 00072 n_vertex = DIM + 1, 00073 n_boundary = DIM + 1, 00074 n_child = (1<<DIM) 00075 }; 00076 }; 00077 00078 template <> 00079 struct HGeometryInfo<0> { 00080 enum { 00081 dimension = 0, 00082 n_vertex = 0, 00083 n_boundary = 0, 00084 n_child = 0 00085 }; 00086 }; 00087 00088 template <> 00089 struct HGeometryInfo<1> { 00090 enum { 00091 dimension = 1, 00092 n_vertex = 2, 00093 n_boundary = 0, 00094 n_child = 2 00095 }; 00096 }; 00097 00098 typedef int bmark_t; 00099 00100 #include "PropertyTable.h" 00101 00102 #ifdef __SERIALIZATION__ 00103 #include "Migration.h" 00104 struct HBuffer : public PropertyTable { 00105 typedef Migration::buffer_t buffer_t; 00106 buffer_t buffer; 00107 virtual ~HBuffer() {} 00108 }; 00109 #else 00110 struct HBuffer : public PropertyTable { 00111 virtual ~HBuffer() {} 00112 }; 00113 #endif // __SERIALIZATION__ 00114 00124 struct HTools { 00125 00126 enum { USED = -8, UNUSED = -7, 00127 INACTIVE = -9, ACTIVE = USED }; 00128 00130 00138 template <class GEO> bool 00139 isGeometryUsed(const GEO& geo) const { 00140 return (geo.index == USED); 00141 } 00142 00146 template <class GEO> bool 00147 isGeometryActive(const GEO& geo) const { 00148 return (geo.index == ACTIVE); 00149 } 00150 00154 template <class GEO> bool 00155 isGeometryInactive(const GEO& geo) const { 00156 return (geo.index == INACTIVE); 00157 } 00158 00162 template <class GEO> bool 00163 isGeometryIndexed(const GEO& geo) const { 00164 return (geo.index >= 0); 00165 } 00167 00169 00177 template <class GEO> void 00178 setGeometryUsed(GEO& geo) const { 00179 geo.index = USED; 00180 for (u_int i = 0;i < GEO::n_boundary;++ i) { 00181 this->setGeometryUsed(*geo.boundary[i]); 00182 } 00183 } 00184 template <int DOW> void 00185 setGeometryUsed(HGeometry<0,DOW>& geo) const { 00186 geo.index = USED; 00187 } 00188 template <int DOW> void 00189 setGeometryUsed(HGeometry<1,DOW>& geo) const { 00190 geo.index = USED; 00191 } 00192 template <class GEO> void 00193 setGeometryActive(GEO& geo) const { 00194 setGeometryUsed(geo); 00195 } 00197 00199 00202 template <class GEO> void 00203 setGeometryUnused(GEO& geo) const { 00204 geo.index = UNUSED; 00205 for (u_int i = 0;i < GEO::n_boundary;++ i) { 00206 this->setGeometryUnused(*geo.boundary[i]); 00207 } 00208 } 00209 template <int DOW> void 00210 setGeometryUnused(HGeometry<1,DOW>& geo) const { 00211 geo.index = UNUSED; 00212 } 00214 00216 00219 template <class GEO> void 00220 setGeometryInactive(GEO& geo) const { 00221 geo.index = INACTIVE; 00222 for (u_int i = 0;i < GEO::n_boundary;++ i) { 00223 this->setGeometryInactive(*geo.boundary[i]); 00224 } 00225 } 00226 template <int DOW> void 00227 setGeometryInactive(HGeometry<1,DOW>& geo) const { 00228 geo.index = INACTIVE; 00229 } 00231 00235 template <class GEO> void 00236 setGeometryUnusedRecursively(GEO& geo) const { 00237 setGeometryUnused(geo); 00238 00239 if (geo.isRefined()) { 00240 for (u_int i = 0;i < GEO::n_child;++ i) { 00241 this->setGeometryUnusedRecursively(*geo.child[i]); 00242 } 00243 } 00244 } 00246 00250 template <class GEO> bool 00251 isRefined(const GEO& geo) const { 00252 if (geo.isRefined()) { 00253 return this->isGeometryUsed(*geo.child[0]); 00254 } else { 00255 return false; 00256 } 00257 } 00258 00265 template <int DOW> bool 00266 isSemiregular(const HGeometry<1,DOW>& geo) const { 00267 assert (this->isGeometryUsed(geo)); 00268 00269 bool result = true; 00270 if (geo.isRefined()) { 00271 if (this->isRefined(*geo.child[0]) || 00272 this->isRefined(*geo.child[1])) { 00273 result = false; 00274 } 00275 } 00276 return result; 00277 } 00278 00287 template <int DOW> bool 00288 isSemiregular(const HGeometry<2,DOW>& geo) const { 00289 assert (this->isGeometryUsed(geo)); 00290 00291 u_int n_refined_edge = 0; 00292 for (u_int i = 0;i < HGeometryInfo<2>::n_boundary;++ i) { 00293 const HGeometry<1,DOW>& edge = *geo.boundary[i]; 00294 if(! this->isSemiregular(edge)) return false; 00295 if (this->isRefined(edge)) { 00296 n_refined_edge += 1; 00297 } 00298 } 00299 bool result = (n_refined_edge <= 1); 00300 return result; 00301 } 00302 00310 template <int DOW> bool 00311 isSemiregular(const HGeometry<3,DOW>& geo) const { 00312 assert (this->isGeometryUsed(geo)); 00313 00314 u_int n_refined_edge = 0; 00315 u_int n_refined_face = 0; 00316 for (u_int i = 0;i < HGeometryInfo<3>::n_boundary;++ i) { 00317 const HGeometry<2,DOW>& face = *geo.boundary[i]; 00318 u_int n_refined_face_edge = 0; 00319 for (u_int j = 0;j < HGeometryInfo<2>::n_boundary;++ j) { 00320 const HGeometry<1,DOW>& edge = *face.boundary[j]; 00321 if (! this->isSemiregular(edge)) return false; 00322 if (this->isRefined(edge)) { 00323 n_refined_face_edge += 1; 00324 } 00325 } 00326 if (n_refined_face_edge == 3) n_refined_face += 1; 00327 n_refined_edge += n_refined_face_edge; 00328 } 00329 n_refined_edge /= 2; // 每条边都被算了两遍 00330 bool result = (n_refined_edge <= 1 || 00331 (n_refined_edge == 3 && 00332 n_refined_face == 1)); 00333 return result; 00334 } 00335 00339 template <class GEO> void 00340 setParentInactive(GEO& geo) const { 00341 if (geo.parent == NULL) return; 00342 setGeometryInactive(*geo.parent); 00343 } 00344 00346 00359 template <class GEO> void 00360 clearIndex(GEO& geo) const { 00361 geo.index = 0; 00362 for (u_int i = 0;i < geo.n_boundary;++ i) { 00363 clearIndex(*geo.boundary[i]); 00364 } 00365 if (geo.isRefined()) { 00366 for (u_int i = 0;i < geo.n_child;++ i) { 00367 clearIndex(*geo.child[i]); 00368 } 00369 } 00370 } 00371 template <int DOW> void 00372 clearIndex(HGeometry<0,DOW>& geo) const { 00373 geo.index = 0; 00374 } 00375 template <int DOW> void 00376 clearIndex(HGeometry<1,DOW>& geo) const { 00377 geo.index = 0; 00378 for (u_int i = 0;i < geo.n_vertex;++ i) { 00379 clearIndex(*geo.vertex[i]); 00380 } 00381 if (geo.isRefined()) { 00382 for (u_int i = 0;i < geo.n_child;++ i) { 00383 clearIndex(*geo.child[i]); 00384 } 00385 } 00386 } 00388 00390 00393 template <class GEO> void 00394 incrIndex(GEO& geo) const { 00395 geo.index += 1; 00396 for (u_int i = 0;i < geo.n_boundary;++ i) { 00397 incrIndex(*geo.boundary[i]); 00398 } 00399 if (geo.isRefined()) { 00400 for (u_int i = 0;i < geo.n_child;++ i) { 00401 incrIndex(*geo.child[i]); 00402 } 00403 } 00404 } 00405 template <int DOW> void 00406 incrIndex(HGeometry<0,DOW>& geo) const { 00407 geo.index += 1; 00408 } 00409 template <int DOW> void 00410 incrIndex(HGeometry<1,DOW>& geo) const { 00411 geo.index += 1; 00412 for (u_int i = 0;i < geo.n_vertex;++ i) { 00413 incrIndex(*geo.vertex[i]); 00414 } 00415 if (geo.isRefined()) { 00416 for (u_int i = 0;i < geo.n_child;++ i) { 00417 incrIndex(*geo.child[i]); 00418 } 00419 } 00420 } 00422 00424 00427 template <class GEO> void 00428 decrIndex(GEO& geo) const { 00429 geo.index -= 1; 00430 if (geo.isRefined()) { 00431 for (u_int i = 0;i < geo.n_child;++ i) { 00432 decrIndex(*geo.child[i]); 00433 } 00434 } 00435 for (u_int i = 0;i < geo.n_boundary;++ i) { 00436 decrIndex(*geo.boundary[i]); 00437 } 00438 if (geo.index == 0) delete &geo; 00439 } 00440 template <int DOW> void 00441 decrIndex(HGeometry<0,DOW>& geo) const { 00442 geo.index -= 1; 00443 if (geo.index == 0) delete &geo; 00444 } 00445 template <int DOW> void 00446 decrIndex(HGeometry<1,DOW>& geo) const { 00447 geo.index -= 1; 00448 if (geo.isRefined()) { 00449 for (u_int i = 0;i < geo.n_child;++ i) { 00450 decrIndex(*geo.child[i]); 00451 } 00452 } 00453 for (u_int i = 0;i < geo.n_vertex;++ i) { 00454 decrIndex(*geo.vertex[i]); 00455 } 00456 if (geo.index == 0) delete &geo; 00457 } 00459 00460 00462 template <class HGEO, class VTX> void 00463 regularize_add_node(HGEO& hgeo, 00464 GeometryBM& geo, 00465 VTX& vtx) const { 00466 int idx = hgeo.index; 00467 if (geo.index() == -1) { 00468 vtx = hgeo; 00469 00470 geo.index() = idx; 00471 geo.vertex().resize(1, idx); 00472 geo.boundary().resize(1, idx); 00473 geo.boundaryMark() = hgeo.bmark; 00474 } 00475 } 00476 00477 template <class HGEO> void 00478 regularize_add_side(HGEO& hgeo, 00479 GeometryBM& geo) const { 00480 int idx = hgeo.index; 00481 if (geo.index() == -1) { 00482 geo.index() = idx; 00483 00484 geo.vertex().resize(2); 00485 geo.vertex(0) = hgeo.vertex[0]->index; 00486 geo.vertex(1) = hgeo.vertex[1]->index; 00487 00488 geo.boundary().resize(2); 00489 geo.boundary(0) = hgeo.vertex[0]->index; 00490 geo.boundary(1) = hgeo.vertex[1]->index; 00491 00492 geo.boundaryMark() = hgeo.bmark; 00493 } 00494 } 00495 00496 template <class HGEO> void 00497 regularize_add_triangle(HGEO& hgeo, 00498 GeometryBM& geo) const { 00499 int idx = hgeo.index; 00500 if (geo.index() == -1) { 00501 geo.index() = idx; 00502 00503 geo.vertex().resize(3); 00504 geo.vertex(0) = hgeo.vertex[0]->index; 00505 geo.vertex(1) = hgeo.vertex[1]->index; 00506 geo.vertex(2) = hgeo.vertex[2]->index; 00507 00508 geo.boundary().resize(3); 00509 geo.boundary(0) = hgeo.boundary[0]->index; 00510 geo.boundary(1) = hgeo.boundary[1]->index; 00511 geo.boundary(2) = hgeo.boundary[2]->index; 00512 00513 geo.boundaryMark() = hgeo.bmark; 00514 } 00515 } 00516 00517 template <class HGEO> void 00518 regularize_add_twin_triangle(HGEO& hgeo, 00519 GeometryBM& geo, 00520 int k) const { 00521 int idx = hgeo.index; 00522 int ii[] = {0,1,2,0,1,2,0,1,2}; 00523 if (geo.index() == -1) { 00524 geo.index() = idx; 00525 00526 geo.vertex().resize(4); 00527 geo.vertex(0) = hgeo.vertex[k]->index; 00528 geo.vertex(1) = hgeo.vertex[ii[k + 1]]->index; 00529 geo.vertex(2) = hgeo.boundary[k]->child[0]->vertex[1]->index; 00530 geo.vertex(3) = hgeo.vertex[ii[k + 2]]->index; 00531 00532 geo.boundary().resize(4); 00533 geo.boundary(0) = hgeo.boundary[ii[k + 2]]->index; 00534 if (hgeo.boundary[k]->child[0]->vertex[0] == hgeo.vertex[ii[k + 1]]) { 00535 geo.boundary(1) = hgeo.boundary[k]->child[0]->index; 00536 geo.boundary(2) = hgeo.boundary[k]->child[1]->index; 00537 } else { 00538 geo.boundary(1) = hgeo.boundary[k]->child[1]->index; 00539 geo.boundary(2) = hgeo.boundary[k]->child[0]->index; 00540 } 00541 geo.boundary(3) = hgeo.boundary[ii[k + 1]]->index; 00542 00543 geo.boundaryMark() = hgeo.bmark; 00544 } 00545 } 00547 }; 00548 00554 template <int DIM, int DOW=DIM> 00555 class HGeometry : public HGeometryInfo<DIM>, public HBuffer 00556 { 00557 public: 00558 enum { dim = DIM, dow = DOW }; 00559 typedef HGeometry<0,dow> vertex_t; 00560 typedef HGeometry<dim-1,dow> bound_t; 00561 typedef HGeometry<dim,dow> this_t; 00562 typedef this_t child_t; 00563 typedef this_t parent_t; 00564 00565 int index; 00566 std::vector<vertex_t *> vertex; 00567 std::vector<bound_t *> boundary; 00568 parent_t * parent; 00569 std::vector<child_t *> child; 00570 bmark_t bmark; 00571 00572 public: 00573 HGeometry(); 00574 virtual ~HGeometry() {} 00575 00576 public: 00577 bool isRefined() const; 00578 bool isIncludePoint(const Point<DOW>&) const; 00579 void refine(); 00580 void checkIntegrity() const; 00581 00582 friend std::ostream& operator<< <>(std::ostream&, const HGeometry<DIM,DOW>&); 00583 }; 00584 00590 template <int DOW> 00591 class HGeometry<0,DOW> : public Point<DOW>, public HGeometryInfo<0>, public HBuffer 00592 { 00593 public: 00594 enum { dim = 0, dow = DOW }; 00595 typedef HGeometry<dim,dow> this_t; 00596 typedef this_t vertex_t; 00597 typedef this_t bound_t; 00598 typedef this_t child_t; 00599 typedef this_t parent_t; 00600 00601 int index; 00602 bmark_t bmark; 00603 00604 static parent_t * parent; 00605 static std::vector<vertex_t *> vertex; 00606 static std::vector<bound_t *> boundary; 00607 static std::vector<child_t *> child; 00608 public: 00609 HGeometry(); 00610 virtual ~HGeometry() {} 00611 00612 bool isRefined() const { return false; } 00613 void refine() {} 00614 }; 00615 00616 00617 00618 template <int DOW=1> 00619 class HGeometry<1,DOW> : public HGeometryInfo<1>, public HBuffer 00620 { 00621 public: 00622 enum { dim = 1, dow = DOW }; 00623 typedef HGeometry<0,dow> vertex_t; 00624 typedef HGeometry<dim-1,dow> bound_t; 00625 typedef HGeometry<dim,dow> this_t; 00626 typedef this_t child_t; 00627 typedef this_t parent_t; 00628 00629 static void (*mid_point)(const Point<DOW>&, 00630 const Point<DOW>&, 00631 bmark_t, 00632 Point<DOW>&); 00633 public: 00634 int index; 00635 std::vector<vertex_t *> vertex; 00636 std::vector<bound_t *> boundary; 00637 parent_t * parent; 00638 std::vector<HGeometry<1,DOW> *> child; 00639 bmark_t bmark; 00640 public: 00641 HGeometry(); 00642 virtual ~HGeometry() {} 00643 public: 00644 bool isRefined() const; 00645 bool isIncludePoint(const Point<DOW>&) const; 00646 void refine(); 00647 void checkIntegrity() const; 00648 00649 friend std::ostream& operator<< <>(std::ostream&, const HGeometry<1,DOW>&); 00650 }; 00651 00652 template <int DOW=2> 00653 class HGeometry<2,DOW> : public HGeometryInfo<2>, public HBuffer 00654 { 00655 public: 00656 enum { dim = 2, dow = DOW }; 00657 typedef HGeometry<0,dow> vertex_t; 00658 typedef HGeometry<dim-1,dow> bound_t; 00659 typedef HGeometry<dim,dow> this_t; 00660 typedef this_t child_t; 00661 typedef this_t parent_t; 00662 00663 int index; 00664 std::vector<vertex_t *> vertex; 00665 std::vector<bound_t *> boundary; 00666 parent_t * parent; 00667 std::vector<child_t *> child; 00668 bmark_t bmark; 00669 public: 00670 HGeometry(); 00671 virtual ~HGeometry() {} 00672 public: 00673 bool isRefined() const; 00674 bool isIncludePoint(const Point<DOW>&) const; 00675 void refine(); 00676 void checkIntegrity() const; 00677 00678 friend std::ostream& operator<< <>(std::ostream&, const HGeometry<2,DOW>&); 00679 }; 00680 00681 template <int DOW=3> 00682 class HGeometry<3,DOW> : public HGeometryInfo<3>, public HBuffer 00683 { 00684 public: 00685 enum { dim = 3, dow = DOW }; 00686 typedef HGeometry<0,dow> vertex_t; 00687 typedef HGeometry<dim-1,dow> bound_t; 00688 typedef HGeometry<dim,dow> this_t; 00689 typedef this_t child_t; 00690 typedef this_t parent_t; 00691 00692 static const int REFINE_MODEL_03 = 0; 00693 static const int REFINE_MODEL_14 = 1; 00694 static const int REFINE_MODEL_25 = 2; 00695 int refine_model; 00696 public: 00697 int index; 00698 std::vector<vertex_t *> vertex; 00699 std::vector<bound_t *> boundary; 00700 parent_t * parent; 00701 std::vector<child_t *> child; 00702 bmark_t bmark; 00703 public: 00704 HGeometry(); 00705 virtual ~HGeometry() {} 00706 public: 00707 bool isRefined() const; 00708 bool isIncludePoint(const Point<DOW>&) const; 00709 void refine(); 00710 void checkIntegrity() const; 00711 00712 friend std::ostream& operator<< <>(std::ostream&, const HGeometry<3,DOW>&); 00713 }; 00714 00715 00720 template <int DIM, int DOW=DIM> 00721 class HGeometryTree 00722 { 00723 public: 00724 enum { dim = DIM, dow = DOW }; 00725 00726 private: 00727 typedef HGeometry<DIM,DOW> entry_t; 00728 public: 00729 typedef std::list<entry_t *> container_t; 00730 private: 00731 container_t root_element; 00732 00733 bool _is_locked; 00740 public: 00741 typedef _Deref_iterator<typename container_t::iterator, entry_t> RootIterator; 00742 typedef _Deref_iterator<typename container_t::const_iterator, const entry_t> ConstRootIterator; 00743 00744 typedef HTools Tools; 00745 public: 00746 HGeometryTree() : _is_locked(false) {}; 00747 virtual ~HGeometryTree() {clear();}; 00748 00749 protected: 00750 bool lock() { 00751 if (_is_locked) return false; 00752 else { 00753 _is_locked = true; 00754 return true; 00755 } 00756 } 00757 void unlock() { 00758 _is_locked = false; 00759 } 00760 00761 public: 00762 container_t& rootElement() { return root_element; } 00763 const container_t& rootElement() const { return root_element; } 00764 00765 unsigned int n_rootElement() const {return root_element.size();} 00766 00767 RootIterator beginRootElement() {return RootIterator(root_element.begin());} 00768 RootIterator endRootElement() {return RootIterator(root_element.end());} 00769 00770 ConstRootIterator beginRootElement() const {return ConstRootIterator(root_element.begin());} 00771 ConstRootIterator endRootElement() const {return ConstRootIterator(root_element.end());} 00772 00773 void clear(); // this method need very complex implementation, left for future 00774 void checkIntegrity(); 00775 00776 bool is_locked() const { return _is_locked; } 00777 bool& is_locked() { return _is_locked; } 00778 00783 void readEasyMesh(const std::string&); 00784 00788 void readMesh(const std::string&); 00789 00790 friend class IrregularMesh<DIM, DOW>; 00791 }; 00792 00793 00794 00802 template <int DIM, int DOW=DIM> 00803 class HElement : public HGeometryInfo<DIM>, public HBuffer { 00804 public: 00805 enum { dim = DIM, dow = DOW }; 00806 typedef HGeometry<dim,dow> h_element_t; 00807 typedef HElement<dim,dow> element_t; 00808 typedef element_t parent_t; 00809 typedef element_t child_t; 00810 00811 public: 00812 typedef int ElementType; 00813 static const ElementType NOT_ACTIVE = -1; 00814 00815 // for 2 dimensional case 00816 static const ElementType TRIANGLE = 0; 00817 static const ElementType QUADRILATERAL = 1; 00818 00819 // for 3 dimensional case 00820 static const ElementType TETRAHEDRON = 0; 00821 static const ElementType TWIN_TETRAHEDRON = 1; 00822 static const ElementType FOUR_TETRAHEDRON = 2; 00823 public: 00824 int index; 00825 double indicator; 00826 int value; // default: -1 00827 h_element_t * h_element; // default: NULL 00828 element_t * parent; // default: NULL 00829 std::vector<element_t *> child; // default: NULL 00830 public: 00831 HElement(); 00832 HElement(const element_t&); 00833 virtual ~HElement(); 00834 public: 00835 element_t& operator=(const element_t&); 00836 /* bool is_dummy() const { return h_element->is_dummy(); } */ 00837 bool isRefined() const; 00838 bool isIncludePoint(const Point<DOW>&) const; 00839 void refine(); 00840 void checkIntegrity() const; 00841 00842 friend std::ostream& operator<< <>(std::ostream&, const HElement<DIM, DOW>&); 00843 }; 00844 00845 00846 00858 template <int DIM, int DOW=DIM> 00859 class IrregularMesh 00860 { 00861 public: 00862 enum { dim = DIM, dow = DOW }; 00863 typedef RegularMesh<DIM,DOW> mesh_t; 00864 typedef HGeometryTree<DIM,DOW> tree_t; 00865 typedef IrregularMesh<DIM,DOW> ir_mesh_t; 00866 00867 protected: 00868 typedef HGeometry<DIM,DOW> h_element_t; 00869 typedef HElement<DIM,DOW> element_t; 00870 typedef std::list<element_t *> container_t; 00871 typedef HTools Tools; 00872 00873 private: 00874 tree_t * geometry_tree; // default: NULL 00875 container_t root_element; // default: NULL 00876 mesh_t * regular_mesh; // default: NULL 00877 00878 public: 00879 typedef _Deref_iterator<typename container_t::iterator, element_t> RootIterator; 00880 typedef _Deref_iterator<typename container_t::const_iterator, const element_t> ConstRootIterator; 00881 00882 typedef RootFirstElementIterator<DIM, DOW> RootFirstIterator; 00883 typedef ActiveElementIterator<DIM, DOW> ActiveIterator; 00884 00885 public: 00886 IrregularMesh(); 00887 explicit IrregularMesh(tree_t&); 00888 IrregularMesh(const ir_mesh_t&); 00889 virtual ~IrregularMesh(); 00890 00891 public: 00892 void clear(); 00893 ir_mesh_t& operator=(const ir_mesh_t&); 00894 00895 public: 00896 RootIterator beginRootElement() {return root_element.begin();} 00897 RootIterator endRootElement() {return root_element.end();} 00898 00899 ConstRootIterator beginRootElement() const {return root_element.begin();}; 00900 ConstRootIterator endRootElement() const {return root_element.end();}; 00901 00902 RootFirstIterator beginRootFirstElement(); 00903 RootFirstIterator endRootFirstElement(); 00904 00905 ActiveIterator beginActiveElement(); 00906 ActiveIterator endActiveElement(); 00907 00908 public: 00920 void reinit(tree_t& htree, bool is_bare = false); 00921 tree_t& geometryTree() const {return *geometry_tree;}; 00922 container_t& rootElement() {return root_element;}; 00923 mesh_t& regularMesh() {return *regular_mesh;}; 00924 const mesh_t& regularMesh() const {return *regular_mesh;}; 00925 00926 virtual void semiregularize(); 00927 void regularize(bool renumerate = true); 00928 void globalRefine(unsigned int i = 1); 00929 void randomRefine(double percent = 50.0); 00930 void writeFormatted(const std::string&); 00931 00932 void copyTree(const ir_mesh_t&); 00933 void copyNonnegtiveSubtree(const ir_mesh_t&); 00934 00935 void copyTree(const element_t *, element_t *); 00936 void copyNonnegtiveSubtree(const element_t *, element_t *); 00937 00938 void deleteTree(element_t *); 00939 00940 friend std::ostream& operator<< <>(std::ostream&, IrregularMesh<DIM, DOW>&); 00941 friend class IrregularMeshPair<DIM, DOW>; 00942 00943 protected: 00944 void checkIntegrity(); 00945 void setGeometryTree(tree_t *); 00946 00947 void semiregularizeHelper(bool&, int&); 00948 void semiregularizeHelper(bool&, element_t&, int&); 00949 00950 void prepareSemiregularize(); 00951 void prepareSemiregularizeHelper(h_element_t *); 00952 00953 void renumerateElement(); 00954 00955 void refineElement(element_t& h_ele); 00956 00957 public: 00958 friend class RegularMesh<DIM, DOW>; 00959 }; 00960 00961 00962 00968 template <int DIM, int DOW=DIM> 00969 class RegularMesh : public Mesh<DIM,DOW> 00970 { 00971 public: 00972 enum { dim = DIM, dow = DOW }; 00973 typedef IrregularMesh<DIM,DOW> ir_mesh_t; 00974 typedef RegularMesh<DIM,DOW> mesh_t; 00975 00976 private: 00977 ir_mesh_t * irregular_mesh; 00978 00979 #ifdef __SERIALIZATION__ 00980 std::vector<std::vector<HBuffer*> > h_geometry_ptr; 00981 #endif 00982 00983 private: 00984 RegularMesh() {} 00985 RegularMesh(const mesh_t& m) {} 00986 mesh_t& operator=(const mesh_t& m) {} 00987 explicit RegularMesh(ir_mesh_t * m) : irregular_mesh(m) {}; 00988 public: 00989 ir_mesh_t& irregularMesh() const {return *irregular_mesh;}; 00990 void renumerateElement() {irregular_mesh->renumerateElement();}; 00991 00992 #ifdef __SERIALIZATION__ 00993 std::vector<std::vector<HBuffer*> >& h_geometry() { return h_geometry_ptr;} 00994 const std::vector<std::vector<HBuffer*> >& h_geometry() const { return h_geometry_ptr;} 00995 HBuffer * h_geometry(int dim, u_int idx) const { return h_geometry_ptr[dim][idx]; } 00996 01000 template <int GDIM> HGeometry<GDIM,DOW> * 01001 h_geometry(u_int idx) const { 01002 return (HGeometry<GDIM,DOW> *)h_geometry_ptr[GDIM][idx]; 01003 } 01004 01014 template <class T, int GDIM> T * 01015 new_property(u_int idx, const property_id_t<T>& pid) const { 01016 return this->template h_geometry<GDIM>(idx)->new_property(pid); 01017 } 01027 template <class T, int GDIM> T * 01028 get_property(int idx, const property_id_t<T>& pid) const { 01029 return this->template h_geometry<GDIM>(idx)->get_property(pid); 01030 } 01031 template <class T, int GDIM> void 01032 free_property(int idx, const property_id_t<T>& pid) const { 01033 this->template h_geometry<GDIM>(idx)->free_property(pid); 01034 } 01035 01039 template <class T, int GDIM> T * 01040 new_property(const GeometryBM& geo, const property_id_t<T>& pid) const { 01041 return this->template h_geometry<GDIM>(geo.index())->new_property(pid); 01042 } 01046 template <class T, int GDIM> T * 01047 get_property(const GeometryBM& geo, const property_id_t<T>& pid) const { 01048 return this->template h_geometry<GDIM>(geo.index())->get_property(pid); 01049 } 01050 template <class T, int GDIM> void 01051 free_property(const GeometryBM& geo, const property_id_t<T>& pid) const { 01052 this->template h_geometry<GDIM>(geo.index())->free_property(pid); 01053 } 01054 01058 template <class T> T * 01059 new_property(int dim, 01060 const GeometryBM& geo, 01061 const property_id_t<T>& pid) const { 01062 switch(dim) { 01063 case 0: return this->template new_property<T,0>(geo, pid); 01064 case 1: return this->template new_property<T,1>(geo, pid); 01065 case 2: return this->template new_property<T,2>(geo, pid); 01066 case 3: return this->template new_property<T,3>(geo, pid); 01067 } 01068 } 01078 template <class T> T * 01079 get_property(int dim, 01080 int idx, 01081 const property_id_t<T>& pid) const { 01082 switch(dim) { 01083 case 0: return this->template get_property<T,0>(idx, pid); 01084 case 1: return this->template get_property<T,1>(idx, pid); 01085 case 2: return this->template get_property<T,2>(idx, pid); 01086 case 3: return this->template get_property<T,3>(idx, pid); 01087 } 01088 } 01089 template <class T> void 01090 free_property(int dim, 01091 int idx, 01092 const property_id_t<T>& pid) const { 01093 switch(dim) { 01094 case 0: this->template free_property<T,0>(idx, pid); break; 01095 case 1: this->template free_property<T,1>(idx, pid); break; 01096 case 2: this->template free_property<T,2>(idx, pid); break; 01097 case 3: this->template free_property<T,3>(idx, pid); break; 01098 } 01099 } 01100 01110 template <class T> T * 01111 new_property(int dim, 01112 int idx, 01113 const property_id_t<T>& pid) const { 01114 switch(dim) { 01115 case 0: return this->template new_property<T,0>(idx, pid); 01116 case 1: return this->template new_property<T,1>(idx, pid); 01117 case 2: return this->template new_property<T,2>(idx, pid); 01118 case 3: return this->template new_property<T,3>(idx, pid); 01119 } 01120 } 01124 template <class T> T * 01125 get_property(int dim, 01126 const GeometryBM& geo, 01127 const property_id_t<T>& pid) const { 01128 switch(dim) { 01129 case 0: return this->template get_property<T,0>(geo, pid); 01130 case 1: return this->template get_property<T,1>(geo, pid); 01131 case 2: return this->template get_property<T,2>(geo, pid); 01132 case 3: return this->template get_property<T,3>(geo, pid); 01133 } 01134 } 01135 template <class T> void 01136 free_property(int dim, 01137 const GeometryBM& geo, 01138 const property_id_t<T>& pid) const { 01139 switch(dim) { 01140 case 0: this->template free_property<T,0>(geo, pid); break; 01141 case 1: this->template free_property<T,1>(geo, pid); break; 01142 case 2: this->template free_property<T,2>(geo, pid); break; 01143 case 3: this->template free_property<T,3>(geo, pid); break; 01144 } 01145 } 01146 01147 #endif // __SERIALIZATION__ 01148 01149 template <class LABEL> 01150 void refineLabelled(LABEL& flag) { 01151 typename ir_mesh_t::ActiveIterator 01152 the_ele = irregular_mesh->beginActiveElement(), 01153 end_ele = irregular_mesh->endActiveElement(); 01154 for (;the_ele != end_ele;) { 01155 typename ir_mesh_t::ActiveIterator it = the_ele; 01156 ++ the_ele; 01157 if (flag[it->index]) { 01158 irregular_mesh->refineElement(*it); 01159 } 01160 } 01161 } 01162 template <class LABEL> 01163 void coarsenLabelled(LABEL& flag) { 01164 typedef HElement<DIM,DOW> h_element_t; 01165 std::list<h_element_t *> coarsen_list; 01166 property_id_t<int> pid; 01167 new_property_id(pid); 01168 typename ir_mesh_t::ActiveIterator 01169 the_ele = irregular_mesh->beginActiveElement(), 01170 end_ele = irregular_mesh->endActiveElement(); 01171 for (;the_ele != end_ele;++ the_ele) { 01172 if (flag[the_ele->index]) { 01173 HElement<DIM,DOW> * p_ele = the_ele->parent; 01174 if (p_ele != NULL) { 01175 int * p_prp = p_ele->get_property(pid); 01176 if (p_prp == NULL) { 01177 p_prp = p_ele->new_property(pid); 01178 *p_prp = 1; 01179 } else { 01180 *p_prp += 1; 01181 } 01182 if (*p_prp == p_ele->n_child) { 01183 coarsen_list.push_back(p_ele); 01184 p_ele->free_property(pid); 01185 } 01186 } 01187 } 01188 } 01189 free_property_id(pid); 01190 01191 typename std::list<h_element_t *>::iterator 01192 the_ele_ptr = coarsen_list.begin(), 01193 end_ele_ptr = coarsen_list.end(); 01194 for (;the_ele_ptr != end_ele_ptr;++ the_ele_ptr) { 01195 (*the_ele_ptr)->value = 0; 01196 } 01197 } 01198 01199 void renumerateElementHSFC(void (*f)(double,double,double,double&,double&,double&)=NULL); 01203 virtual void writeEasyMesh(const std::string&) const; 01207 virtual void writeTecplotData(const std::string&) const; 01211 virtual void writeOpenDXData(const std::string&) const; 01218 virtual void writeSimplestSimplexMesh(const std::string&) const; 01222 virtual void writeSimplexMesh(const std::string&) const; 01223 public: 01224 friend class IrregularMesh<DIM,DOW>; 01225 }; 01226 01234 template <int DIM, int DOW=DIM> 01235 class ElementIterator 01236 { 01237 public: 01238 enum { n_child = HGeometry<DIM,DOW>::n_child }; 01239 01240 typedef HElement<DIM,DOW> value_t; 01241 typedef value_t * pointer_t; 01242 typedef value_t& reference_t; 01243 01244 typedef typename std::list<pointer_t>::iterator root_t; 01245 typedef ElementIterator<DIM,DOW> this_t; 01246 typedef IrregularMesh<DIM, DOW> ir_mesh_t; 01247 01248 protected: 01249 ir_mesh_t * mesh; 01250 root_t root_element; 01251 pointer_t element; 01252 01253 public: 01254 ElementIterator(); 01255 ElementIterator(ir_mesh_t *, root_t&, pointer_t); 01256 ElementIterator(const this_t&); 01257 virtual ~ElementIterator(); 01258 01259 public: 01260 this_t& operator=(const this_t&); 01261 01262 const reference_t operator*() const {return *element;}; 01263 reference_t operator*() {return *element;}; 01264 01265 operator const pointer_t() const {return element;}; 01266 operator pointer_t() {return element;}; 01267 01268 const pointer_t operator->() const {return element;}; 01269 pointer_t operator->() {return element;}; 01270 01271 virtual this_t& operator++() = 0; 01272 01273 friend bool operator== <>(const this_t&, this_t&); 01274 friend bool operator!= <>(const this_t&, this_t&); 01275 01276 public: 01277 friend class IrregularMesh<DIM, DOW>; 01278 friend class HElement<DIM, DOW>; 01279 friend class ActiveElementPairIterator<DIM, DOW>; 01280 }; 01281 01282 01283 01288 template <int DIM, int DOW=DIM> 01289 class RootFirstElementIterator : public ElementIterator<DIM, DOW> 01290 { 01291 public: 01292 enum { n_child = HGeometry<DIM,DOW>::n_child }; 01293 01294 typedef ElementIterator<DIM,DOW> base_t; 01295 typedef typename base_t::root_t root_t; 01296 typedef RootFirstElementIterator<DIM,DOW> this_t; 01297 01298 using base_t::mesh; 01299 using base_t::root_element; 01300 using base_t::element; 01301 01302 public: 01303 RootFirstElementIterator() {}; 01304 RootFirstElementIterator(IrregularMesh<DIM, DOW> * m, 01305 root_t& i, 01306 HElement<DIM, DOW> * e) : 01307 base_t::ElementIterator(m, i, e) {}; 01308 public: 01309 virtual this_t& operator++(); 01310 }; 01311 01312 01313 01318 template <int DIM, int DOW=DIM> 01319 class ActiveElementIterator : public RootFirstElementIterator<DIM, DOW> 01320 { 01321 public: 01322 enum { n_child = HGeometry<DIM,DOW>::n_child }; 01323 01324 typedef RootFirstElementIterator<DIM,DOW> base_t; 01325 typedef typename base_t::root_t root_t; 01326 typedef ActiveElementIterator<DIM,DOW> this_t; 01327 public: 01328 ActiveElementIterator() {}; 01329 ActiveElementIterator(IrregularMesh<DIM, DOW> * m, 01330 root_t& i, 01331 HElement<DIM, DOW> * e) : base_t(m, i, e) {}; 01332 ActiveElementIterator(const base_t& it) : base_t(it) {} 01333 public: 01334 virtual this_t& operator++(); 01335 }; 01336 01337 01338 01344 template <int DIM, int DOW=DIM> 01345 class IrregularMeshPair 01346 { 01347 public: 01348 enum { dim = DIM, dow = DOW }; 01349 01350 typedef IrregularMesh<DIM, DOW> ir_mesh_t; 01351 typedef ActiveElementPairIterator<DIM, DOW> iterator; 01352 01353 ir_mesh_t * mesh0; 01354 ir_mesh_t * mesh1; 01355 public: 01356 IrregularMeshPair(ir_mesh_t&, ir_mesh_t&); 01357 IrregularMeshPair(ir_mesh_t *, ir_mesh_t *); 01358 ~IrregularMeshPair(); 01359 public: 01360 iterator beginActiveElementPair(); 01361 iterator endActiveElementPair(); 01362 }; 01363 01364 01365 01373 template <int DIM, int DOW=DIM> 01374 class ActiveElementPairIterator 01375 { 01376 public: 01377 typedef IrregularMeshPair<DIM, DOW> ir_mesh_pair_t; 01378 01379 public: 01380 typedef int State; 01381 static const State GREAT_THAN = -1; // 0 is the ancestor of 1 01382 static const State EQUAL = 0; // equal 01383 static const State LESS_THAN = 1; // 0 is a descendant of 1 01384 01385 private: 01386 typedef RootFirstElementIterator<DIM,DOW> iterator; 01387 typedef ActiveElementPairIterator<DIM,DOW> this_t; 01388 01389 public: 01390 typedef HElement<DIM,DOW> value_t; 01391 typedef value_t& reference_t; 01392 typedef value_t * pointer_t; 01393 01394 ir_mesh_pair_t * mesh_pair; 01395 State st; 01396 iterator iterator0; 01397 iterator iterator1; 01398 01399 public: 01400 ActiveElementPairIterator() : mesh_pair(NULL) {}; 01401 ActiveElementPairIterator(ir_mesh_pair_t * mp, 01402 State s, 01403 const iterator& it0, 01404 const iterator& it1) : 01405 mesh_pair(mp), st(s), iterator0(it0), iterator1(it1) {}; 01406 ActiveElementPairIterator(const this_t&); 01407 ~ActiveElementPairIterator() {}; 01408 01409 public: 01410 const reference_t operator()(u_int i) const { 01411 if (i == 0) return *iterator0; 01412 else if (i == 1) return *iterator1; 01413 else Assert (false, ExcInternalError()); // something must be wrong 01414 } 01415 reference_t operator()(u_int i) { 01416 if (i == 0) return *iterator0; 01417 else if (i == 1) return *iterator1; 01418 else { 01419 Assert (false, ExcInternalError()); // something must be wrong 01420 return *((HElement<DIM, DOW> *)NULL); 01421 } 01422 }; 01423 01424 const State& state() const {return st;}; 01425 01426 this_t& operator=(const this_t&); 01427 this_t& operator++(); 01428 01429 friend bool operator== <>(const this_t&, this_t&); 01430 friend bool operator!= <>(const this_t&, this_t&); 01431 public: 01432 friend class IrregularMeshPair<DIM, DOW>; 01433 }; 01434 01435 01436 01443 template <int DIM, int DOW=DIM> 01444 class Indicator : public std::vector<double> 01445 { 01446 public: 01447 enum { dim = DIM, dow = DOW }; 01448 typedef RegularMesh<DIM, DOW> mesh_t; 01449 01450 public: 01451 mesh_t * msh; 01452 public: 01453 Indicator() : msh(NULL) {}; 01454 explicit Indicator(mesh_t& m) : msh(&m) { 01455 resize(msh->n_geometry(DIM)); 01456 }; 01457 ~Indicator() {}; 01458 public: 01459 const mesh_t& mesh() const {return *msh;} 01460 void reinit(mesh_t& m, bool is_bare = false) { 01461 msh = &m; 01462 if (! is_bare) { 01463 resize(msh->n_geometry(DIM)); 01464 std::fill(begin(), end(), 0.0); 01465 } 01466 } 01467 }; 01468 01469 01470 01484 template <int DIM, int DOW=DIM> 01485 class MeshAdaptor 01486 { 01487 public: 01488 enum { dim = DIM, dow = DOW }; 01489 typedef IrregularMesh<DIM,DOW> ir_mesh_t; 01490 typedef Indicator<DIM,DOW> indicator_t; 01491 01492 private: 01493 ir_mesh_t * from_mesh; 01494 ir_mesh_t * to_mesh; 01495 indicator_t * ind; 01496 double tol; 01497 double convergence_order; 01498 int refine_step; 01499 double refine_threshold; 01500 double coarse_threshold; 01501 01502 bool _is_refine_only; 01503 01504 public: 01505 MeshAdaptor(); 01506 explicit MeshAdaptor(ir_mesh_t& f); 01507 MeshAdaptor(ir_mesh_t& f, ir_mesh_t& t); 01508 ~MeshAdaptor(); 01509 01510 public: 01511 void reinit(ir_mesh_t& f) {from_mesh = &f; to_mesh = &f;}; 01512 void reinit(ir_mesh_t& f, ir_mesh_t& t) {from_mesh = &f; to_mesh = &t;}; 01513 const ir_mesh_t& fromMesh() const {return *from_mesh;}; 01514 void setFromMesh(ir_mesh_t& f) {from_mesh = &f;}; 01515 const ir_mesh_t& toMesh() const {return *to_mesh;}; 01516 void setToMesh(ir_mesh_t& t) {to_mesh = &t;}; 01517 const indicator_t& indicator() const {return *ind;}; 01518 const double& indicator(const int& i) const {return (*ind)[i];}; 01519 double& indicator(const int& i) {return (*ind)[i];}; 01520 void setIndicator(indicator_t& i) { 01521 ind = &i; 01522 Assert (&(ind->mesh()) == &(from_mesh->regularMesh()), ExcInternalError()); 01523 }; 01524 const double& tolerence() const {return tol;}; 01525 double& tolerence() {return tol;}; 01526 const double& convergenceOrder() const {return convergence_order;}; 01527 double& convergenceOrder() {return convergence_order;}; 01528 const int& refineStep() const {return refine_step;}; 01529 int& refineStep() {return refine_step;}; 01530 const double& refineThreshold() const {return refine_threshold;}; 01531 double& refineThreshold() {return refine_threshold;}; 01532 const double& coarseThreshold() const {return coarse_threshold;}; 01533 double& coarseThreshold() {return coarse_threshold;}; 01534 01535 bool is_refine_only() const { return _is_refine_only; } 01536 bool& is_refine_only() { return _is_refine_only; } 01537 01538 bool is_indicator_underflow(double ind) const { 01539 return (ind < coarse_threshold*tolerence()); 01540 } 01541 bool is_indicator_overflow(double ind) const { 01542 double convergence_coefficient = pow(2.0, DIM + convergenceOrder()); 01543 return (ind > refine_threshold*convergence_coefficient*tolerence()); 01544 } 01545 bool is_indicator_overflow(double ind, double convergence_coefficient) const { 01546 return (ind > refine_threshold*convergence_coefficient*tolerence()); 01547 } 01548 01549 public: 01550 void globalRefine(unsigned int i = 1); 01551 void randomRefine(double percent = 50.0); 01552 void adapt(); 01553 private: 01554 void collectIndicator(HElement<DIM,DOW>&, double); 01555 void collectIndicator(); 01556 void prepareToMesh(); 01557 void implementAdaption(); 01558 void adaptElement(HElement<DIM,DOW>&, double, int); 01559 }; 01560 01561 #endif // _HGeometry_h_ 01562
1.7.4