RefineVertex.h

Go to the documentation of this file.
00001 #ifndef RefineVertex_HEADER
00002 #define RefineVertex_HEADER
00003 
00004 #ifdef HAVE_CONFIG_H
00005 # include <config.h>
00006 #endif
00007 
00008 #include "MeshTypes.h"
00009 #include <boost/array.hpp>
00010 #include <geometry/Point.h>
00011 #include <refine-common/ConcentricShells.h>
00012 #include <utilities/FastHash.h>
00013 #include <utilities/OrderedHash.h>
00014 #include <utilities/foreach.h>
00015 #include <vector>
00016 
00017 #if 0
00018 #define dprintf(...) printf(__VA_ARGS__);
00019 #define dputs(str) puts(str);
00020 #else
00021 #define dprintf(...)
00022 #define dputs(str)
00023 #endif
00024 
00025 /***************************************************************************
00026  * Vertex for use in the refinement.
00027  *
00028  * This collects:
00029  * -# a geometric point
00030  * -# the ID of the vertex
00031  * -# the containing dimension of the vertex
00032  * -# the set of meshes that contain the vertex
00033  *
00034  ***************************************************************************/
00035 
00036 template <size_t ambient>
00037 class RefineVertex : public boost::noncopyable {
00038   public:
00039   typedef Geometry::Point<ambient> Point;
00040   typedef ::GenericMesh<ambient> Mesh;
00041   typedef ::ConcentricShells<RefineVertex, Point> ConcentricShells;
00042   typedef typename MeshTypes<ambient>::Ball Ball;
00043 
00044   private:
00045   const Point p_;
00046   boost::array<std::vector<const Mesh*>, ambient> uppers_; // top-most is set to NULL
00047   typedef hudson::FastHashMap<const Mesh*, ConcentricShells, hudson::HashPointer<const Mesh> >
00048     Shells;
00049   Shells shells_;
00050   ConcentricShells topShell_;
00051   int id_; //<! id number
00052   int cd_; //<! containing dimension.  Constant.
00053 
00054   Ball *handle_; //<! a top-dimensional ball; any will do.  TODO: this should be a simplex
00055 
00056   public:
00057 
00058   typedef hudson::FastHashSet<RefineVertex*, hudson::HashPointer<RefineVertex> > VertexSet;
00059   typedef hudson::OrderedHashSet<RefineVertex*, hudson::HashPointer<RefineVertex> > VertexUniqueList;
00060 
00065   RefineVertex(const Point& p, unsigned cd = -1): p_(p), id_(-1), cd_(cd), handle_(0) {
00066   }
00067 
00072   void setContainingDimension(unsigned cd) {
00073     assert(cd_ == -1);
00074     assert(int(cd) >= 0);
00075     cd_ = cd;
00076   }
00077 
00081   void replaceHandle(Ball *handle) {
00082     assert(handle->topological() == ambient);
00083     handle_ = handle;
00084   }
00085 
00089   Ball *getHandle() const {
00090     return handle_;
00091   }
00092 
00096   void addUpperMesh(const Mesh *m) {
00097     assert(m);
00098     assert(m->topological() != ambient);
00099     assert(cd_ <= int(m->topological()));
00100     std::vector<const Mesh*>& ups = uppers_[m->topological()];
00101 
00102     /* search for the mesh */
00103     typename std::vector<const Mesh*>::iterator it = std::find(ups.begin(), ups.end(), m);
00104 
00105     if (it != ups.end()) {
00106       /* found, so we need not add it again */
00107       return;
00108     }
00109 
00110     /* Add it and sort.  TODO: be smarter here.  We know inductively that the
00111      * list is sorted.  We had to search for it, so it should now only cost us
00112      * constant or linear time to insert it, not n lg n.  */
00113     dprintf("    %s adding upper %u-mesh %p\n", toString().c_str(), m->topological(), m);
00114     ups.push_back(m);
00115     std::sort(ups.begin(), ups.end());
00116 
00117     /* Now add all that mesh's uppers.  TODO: be much smarter here.  We could
00118      * store the uppers sorted, and then merge, no recursion needed. */
00119     BOUNDED_FOREACH(const Mesh *upper, m->begin_uppers(), m->end_uppers()) {
00120       addUpperMesh(upper);
00121     }
00122 
00123     // Create an empty shell for that level.
00124     shells_.insert(m);
00125   }
00126 
00130   void setID(unsigned id) {
00131     assert(id_ == -1);
00132     assert(int(id) >= 0);
00133     dprintf("  vertex %s is now v%u\n", toString().c_str(), id);
00134     id_ = id;
00135   }
00136 
00138   typedef typename std::vector<const Mesh*>::const_iterator upper_iterator;
00139   upper_iterator begin_uppers(unsigned d) const { return uppers_[d].begin(); }
00140   upper_iterator end_uppers(unsigned d) const { return uppers_[d].end(); }
00141   const std::vector<const Mesh*>& get_uppers(unsigned d) const { return uppers_[d]; }
00142   bool hasUpperMesh(const Mesh *m) const { 
00143     if (m->topological() == ambient) {
00144       return true;
00145     } else {
00146       return shells_.find(m) != shells_.end(); 
00147     }
00148   }
00149 
00151   unsigned getID() const { assert(id_ != -1); return id_; }
00152 
00153   unsigned getCD() const { assert(cd_ != -1); return cd_; }
00154 
00156   double dist2(const RefineVertex *other) const {
00157     return toPoint().dist2(other->toPoint());
00158   }
00159 
00161   struct IsCloser {
00162     const RefineVertex *v_;
00163     IsCloser(const RefineVertex *v): v_(v) { }
00164     bool operator() (const RefineVertex *a, const RefineVertex *b) const {
00165       return a->dist2(v_) < b->dist2(v_);
00166     }
00167   };
00168 
00169   /***************************************************************************
00170    * \name Point location.
00171    *
00172    * Point location information is linked to the particular mesh.
00173    ***************************************************************************/
00174 
00175   private:
00176   ConcentricShells& getShell(const Mesh *m) {
00177     if (m->topological() == ambient) { return topShell_; }
00178     else { return shells_.findOrDie(m); }
00179   }
00180   const ConcentricShells& getShell(const Mesh *m) const {
00181     if (m->topological() == ambient) { return topShell_; }
00182     else { return shells_.findOrDie(m); }
00183   }
00184 
00185   public:
00187   bool isCrowded(const Mesh *m) const {
00188     return ! getShell(m).empty();
00189   }
00190   bool isCrowded() const {
00191     return ! topShell_.empty();
00192   }
00193 
00195   RefineVertex *getFarVertex(const Mesh *m) const {
00196     return getShell(m).getFarItem();
00197   }
00198   RefineVertex *getFarVertex() const {
00199     return topShell_.getFarItem();
00200   }
00201 
00203   void reassignTo(const Mesh *m, RefineVertex *other) {
00204     getShell(m).reassignTo(toPoint(), other->getShell(m), other->toPoint());
00205   }
00206 
00208   void addUninserted(const Mesh *m, RefineVertex *uninserted) {
00209     getShell(m).add(toPoint(), uninserted);
00210   }
00211 
00214   pair<RefineVertex*, double> findClosest(const Mesh *m, const Point& q, double r2) const {
00215     return getShell(m).findClosest(toPoint(), q, r2);
00216   }
00217 
00219   // Requirements of the Vertex signature.
00220 
00222   const Point& toPoint() const { return p_; }
00223 
00225   double x(size_t i) const { return p_[i]; }
00226 
00228   const double *x() const { return p_.data(); }
00229 
00231   std::string toString() const {
00232     char buffer[4096];
00233     if (id_ == -1) {
00234       snprintf(buffer, sizeof(buffer), "v[%u] at %s", cd_, p_.toString().c_str());
00235     } else {
00236       snprintf(buffer, sizeof(buffer), "v%u[%u]", getID(), cd_);
00237     }
00238     return buffer;
00239   }
00240 
00242   struct Printer {
00243     std::string operator()(const RefineVertex *v) const {
00244       return v->toString();
00245     }
00246   };
00247 };
00248 
00249 
00250 
00251 #undef dprintf
00252 #undef dputs
00253 
00254 #endif

Generated on Thu Mar 27 19:04:14 2008 by  doxygen 1.4.6