Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)

cluster/tree.hh
Go to the documentation of this file.
00001 /* Cluster tree
00002  */
00003 
00004 #ifndef clusterTree_hh
00005 #define clusterTree_hh
00006 
00007 #include <iostream>
00008 
00009 #include "basics/typedefs.hh"
00010 #include "basics/vectorsMatricesForward.hh"
00011 #include "basics/exceptions.hh"
00012 #include "space/space.hh"
00013 #include "bem/element.hh"
00014 
00015 namespace cluster {
00016 
00017   // *************************************************************** cebysev **
00018 
00020   void cebysev(const concepts::Real3d& x0, const concepts::Real3d& x1,
00021          concepts::Real3d& c, concepts::Real& r);
00022   void cebysev(const concepts::Real3d& x0, const concepts::Real3d& x1,
00023          const concepts::Real3d& x2, concepts::Real3d& c,
00024          concepts::Real& r);
00025 
00026   // ***************************************************************** BBall **
00027 
00032   template<class F>
00033   class BBall {
00034   public:
00040     virtual void operator()(const concepts::Element<F>& elm,
00041           concepts::Real3d& c, concepts::Real& r) const = 0;
00042   };
00043 
00044   // ************************************************************** BBall000 **
00045 
00049   template<class F>
00050   class BBall000 : public BBall<F> {
00051   public:
00058     void operator()(const concepts::Element<F>& elm, concepts::Real3d& c,
00059         concepts::Real& r) const;
00060   };
00061 
00062   template<class F>
00063   void BBall000<F>::operator()(const concepts::Element<F>& elm,
00064              concepts::Real3d& c, concepts::Real& r) const {
00065 
00066     const bem::Linear3d000<F>* elmA =
00067       dynamic_cast<const bem::Linear3d000<F>*>(&elm);
00068     if (elmA != 0) {
00069       cebysev(elmA->vertex(0), elmA->vertex(1), elmA->vertex(2), c, r);
00070       return; 
00071     }
00072   
00073     const bem::Constant3d000<F>* elmB =
00074       dynamic_cast<const bem::Constant3d000<F>*>(&elm);
00075     if (elmB != 0) {
00076       cebysev(elmB->vertex(0), elmB->vertex(1), elmB->vertex(2), c, r);
00077       return;
00078     }
00079   
00080     const bem::Constant3d001<F>* elmC =
00081       dynamic_cast<const bem::Constant3d001<F>*>(&elm);
00082     if (elmC != 0) {
00083       cebysev(elmC->vertex(0), elmC->vertex(1), elmC->vertex(2), c, r);
00084       return;
00085     }
00086 
00087     const bem::Constant3d002<F>* elmD =
00088       dynamic_cast<const bem::Constant3d002<F>*>(&elm);
00089     if (elmD != 0) {
00090       cebysev(elmD->vertex(0), elmD->vertex(1), elmD->vertex(2), c, r);
00091       return;
00092     }
00093   
00094     const bem::Dirac3d000<F>* elmE =
00095       dynamic_cast<const bem::Dirac3d000<F>*>(&elm);
00096     if (elmE != 0) {
00097       switch (elmE->T().n()) {
00098       case 1:
00099   c = elmE->vertex(0); r = 0.0;
00100   break;
00101       case 2: 
00102   cebysev(elmE->vertex(0), elmE->vertex(1), c, r);
00103   break;
00104       case 3: 
00105   cebysev(elmE->vertex(0), elmE->vertex(1), elmE->vertex(2), c, r);
00106   break;
00107       }
00108       return;
00109     }
00110 
00111     throw conceptsException(concepts::MissingFeature("cell not supported"));
00112   }
00113 
00114   // *************************************************************** Cluster **
00115 
00116   template<typename F>
00117   class Cluster;
00118 
00119   template<typename F>
00120   std::ostream& operator<<(std::ostream& os, const Cluster<F>& clst);
00121 
00125   template<class F>
00126   class Cluster {
00127   public:
00129     typedef F CF;
00130 
00136     Cluster(const concepts::Element<F>& elm, const BBall<F>& ball,
00137       Cluster<F>* lnk);
00145     Cluster(uint idx, Cluster<F>& chld, const concepts::Real3d& c,
00146       concepts::Real r, uint nlf = 0);
00147 
00149     inline Cluster<F>* child(uint j) const;
00151     inline Cluster<F>* child() const;
00153     inline Cluster<F>* link() const {return lnk_;}
00154     inline Cluster<F>*& link() {return lnk_;}
00156     inline const concepts::Element<F>* element() const;
00158     inline const concepts::Real3d& center() const {return c_;}
00160     inline concepts::Real radius() const {return r_;}
00162     inline uint nleaf() const {return nlf_;}
00164     inline uint index() const {return idx_;}
00165     std::ostream& info(std::ostream& os) const;
00166 
00167   private:
00168     friend std::ostream& operator<< <>(std::ostream& os,
00169                const Cluster<F>& clst);
00171     union CE {
00172       Cluster<F>*                 chld;
00173       const concepts::Element<F>* elm;
00174     };
00175 
00177     Cluster<F>* lnk_;
00179     CE          ce_;
00180 
00182     uint idx_;
00184     uint nlf_;
00185 
00187     concepts::Real3d c_;
00189     concepts::Real   r_;
00190   };
00191 
00192   template<class F>
00193   inline Cluster<F>* Cluster<F>::child(uint j) const {
00194     Cluster<F>* c = child();
00195     while (c && j)  {c = c->link();  j--;}
00196     return (j) ? (Cluster<F>*)0 : c;
00197   }
00198 
00199   template<class F>
00200   inline Cluster<F>* Cluster<F>::child() const {
00201     return (nlf_) ? ce_.chld : (Cluster<F>*)0;
00202   }
00203 
00204   template<class F>
00205   inline const concepts::Element<F>* Cluster<F>::element() const {
00206     return (nlf_) ? (concepts::Element<F>*)0 : ce_.elm;
00207   }
00208 
00209   template<class F>
00210   inline std::ostream& operator<<(std::ostream& os, const Cluster<F>& clst) {
00211     return clst.info(os);
00212   }
00213 
00214   template<class F>
00215   Cluster<F>::Cluster(uint idx, Cluster<F>& chld, const concepts::Real3d& c,
00216           concepts::Real r, uint nlf)
00217     : lnk_(0), idx_(idx), nlf_(nlf), c_(c), r_(r) {
00218 
00219     ce_.chld = &chld;
00220 
00221     if (nlf_ == 0)
00222       for(const Cluster<F>* c = &chld; c != 0; c = c->lnk_)
00223   nlf_ += c->nlf_ ? c->nlf_ : 1;
00224   }
00225 
00226   template<class F>
00227   Cluster<F>::Cluster(const concepts::Element<F>& elm,
00228           const BBall<F>& ball, Cluster<F>* lnk)
00229     : lnk_(lnk), idx_(0), nlf_(0) {
00230 
00231     ce_.elm = &elm;
00232     ball(elm, c_, r_);
00233   }
00234 
00235   template<class F>
00236   std::ostream& Cluster<F>::info(std::ostream& os) const {
00237     os << "Cluster(idx = " << idx_ << ", r = " << r_ << ", c = " << c_;
00238     os << ", nleaf = " << nlf_ << ", lnk = " << lnk_;
00239     os << ", chld = " << child() << ')';
00240     return os;
00241   }
00242 
00243   // ************************************************************ TreeTraits **
00244 
00248   template<class Node>
00249   class TreeTraits {
00250   public:
00252     typedef typename Node::CF F;
00253 
00254     static Node* child(const Node* nd, uint j) {return nd->child(j);}
00255     static const concepts::Element<F>* element(const Node* nd) {
00256       return nd->element();
00257     }
00258     static const concepts::Real3d& center(const Node* nd) {
00259       return nd->center();}
00260     
00261     static concepts::Real radius(const Node* nd) {
00262       return nd->radius();
00263     }
00264     static uint nleaf(const Node* nd) {return nd->nleaf();}
00265     static uint index(const Node* nd) {return nd->index();}
00266   };
00267 
00268   // ****************************************************************** Tree **
00269   
00270   template<class CNode>
00271   class Tree;
00272   
00273   template<class CNode>
00274   inline std::ostream& operator<<(std::ostream& os, const Tree<CNode>& t) {
00275     return t.info(os);
00276   }
00277 
00281   template<class CNode>
00282   class Tree {
00283     friend std::ostream& operator<< <>(std::ostream& os, const Tree<CNode>& t);
00284 
00285   public:
00287     typedef TreeTraits<CNode> Traits;
00289     typedef typename Traits::F F;
00291     typedef CNode Node;
00292 
00296     inline Tree(const concepts::Space<F>& spc) : spc_(spc) {}
00297     virtual ~Tree() {}
00298 
00299     virtual std::ostream& info(std::ostream& os) const;
00301     virtual uint nclst() const = 0;
00303     virtual uint nleaf() const = 0;
00305     virtual const Node* root() const = 0;
00307     inline const concepts::Space<F>& space() const {return spc_;}
00308 
00309  private:
00311     const concepts::Space<F>& spc_;
00312 
00321     void info_(const Node* clst, concepts::Real& rhomin,
00322          concepts::Real& rhomax, concepts::Real& taumin,
00323          concepts::Real& taumax, uint& h) const;
00324   };
00325 
00326   template<class CNode>
00327   void Tree<CNode>::info_(const CNode* clst, concepts::Real& rhomin,
00328         concepts::Real& rhomax, concepts::Real& taumin,
00329         concepts::Real& taumax, uint& h) const {
00330     uint j = 0;
00331     const CNode* chld = Traits::child(clst, j);
00332 
00333     while (chld) {
00334       if (Traits::nleaf(chld)) {
00335   uint hh = 0;
00336   info_(chld, rhomin, rhomax, taumin, taumax, hh);
00337 
00338   if (hh > h) h = hh;
00339 
00340   concepts::Real rho = Traits::radius(chld) / Traits::radius(clst);
00341   if (rho < rhomin) rhomin = rho;
00342   if (rho > rhomax) rhomax = rho;
00343 
00344   concepts::Real tau =
00345     (concepts::Real)Traits::nleaf(chld) / Traits::nleaf(clst);
00346   if (tau < taumin) taumin = tau;
00347   if (tau > taumax) taumax = tau;
00348 
00349   if (rho > 2) {
00350     std::cout << *clst << std::endl;
00351     std::cout << *chld << std::endl;
00352   }
00353 
00354       }
00355       chld = Traits::child(clst, ++j);
00356     }
00357     ++h;
00358   }
00359 
00360   template<class CNode>
00361   std::ostream& Tree<CNode>::info(std::ostream& os) const {
00362 
00363     concepts::Real rhomin = 1, rhomax = 0;
00364     concepts::Real taumin = 1, taumax = 0;
00365     uint h = 0;
00366 
00367     info_(root(), rhomin, rhomax, taumin, taumax, h);
00368 
00369     os << "cluster::Tree(nclst = " << nclst() << ", nleaf = " << nleaf();
00370     os << ", h = " << h;
00371 
00372     if (h > 1) {
00373       os << ", rho in [" << rhomin << ", " << rhomax;
00374       os << "], tau in [" << taumin << ", " << taumax << "])";
00375     } else {
00376       os << ')';
00377     }
00378 
00379     return os;
00380   }
00381 
00382 } // namespace cluster
00383 
00384 #endif // clusterTree_hh

Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)