AFEPack
HGeometry.h
浏览该文件的文档。
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