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

aglowav2/element.hh
Go to the documentation of this file.
00001 /* Agglomerated wavelet elements
00002  */
00003 
00004 #ifndef aglowav2Element_hh
00005 #define aglowav2Element_hh
00006 
00007 #ifdef __GUNG__
00008 #pragma interface
00009 #endif
00010 
00011 #include "basics/vectorsMatricesForward.hh"
00012 #include "space/tmatrix.hh"
00013 #include "space/element.hh"
00014 #include "bem/element.hh"
00015 
00016 namespace aglowav2 {
00017 
00018   // ************************************************************* Haar3dXXX **
00019 
00023   template<class F = concepts::Real>
00024   class Haar3dXXX : public concepts::Element<F> {
00025   public:
00028     class Key {
00029     public:
00030       inline Key() : l_(0), j_(0) {}
00035       inline Key(uint l, uint j) : l_(l), j_(j) {}
00036       inline Key(const Key& k) : l_(k.l()), j_(k.j()) {}
00037 
00038       int operator==(const Key& k) const {return l_ == k.l() && j_ == k.j();}
00039       int operator<(const Key& k) const {
00040   return l_ < k.l() || (l_ == k.l() && j_ < k.j());
00041       }
00042       inline uint& l() {return l_;}
00043       inline uint l() const {return l_;}
00044       inline uint& j() {return j_;}
00045       inline uint j() const {return j_;}
00046 
00047     private:
00048       uint l_;
00049       uint j_;
00050     };
00051 
00053     inline Haar3dXXX(const concepts::Real3d& cntr, concepts::Real rd,
00054          concepts::Real sz, const Key& key = Key());
00056     virtual ~Haar3dXXX(){};
00057 
00059     inline const Key& key() const {return key_;}
00060     inline Key& key() {return key_;}
00062     inline const concepts::Real3d& center() const {return cntr_;}
00064     inline concepts::Real radius() const {return rd_;}
00066     inline concepts::Real size() const {return sz_;}
00067 
00069     virtual Haar3dXXX<F>* child() const = 0;
00071     virtual Haar3dXXX<F>* link() const = 0;
00072 
00073   private:
00074     concepts::Real3d cntr_;
00075     concepts::Real   rd_;
00076     Key key_;
00077     concepts::Real   sz_;
00078   };
00079 
00080   template<class F>
00081   Haar3dXXX<F>::Haar3dXXX(const concepts::Real3d& cntr, concepts::Real rd,
00082         concepts::Real sz, const Key& key)
00083     : cntr_(cntr), rd_(rd), key_(key), sz_(sz) {
00084   }
00085 
00086   // **************************************************************** Matrix **
00087 
00092   template<class F = concepts::Real>
00093   class Matrix {
00094   public:
00101     inline Matrix(uint n, uint m, F* val, bool row)
00102       : n_(n), m_(m), val_(val), row_(row) {}
00103 
00104     inline const F* source() const {return val_;}
00105     inline F* destination() const {return val_;}
00106     inline uint nrow() const {return n_;}
00107     inline uint ncol() const {return m_;}
00108     inline bool roworder() const {return row_;}
00109     inline void transpose() {
00110       row_ = row_ ? 0 : 1;  uint n = n_;  n_ = m_;  m_ = n;
00111     }
00112 
00113   private:
00114     uint n_;
00115     uint m_;
00116     F*   val_;
00117     bool row_;
00118   };
00119 
00120 
00121   // ****************************************************************** M000 **
00122 
00125   class M000 {
00126   public:
00127     friend std::ostream& operator<<(std::ostream& os, const M000& m);
00128 
00133     M000(const concepts::Real* m, uint n);
00135     ~M000() {if (m_) delete[] m_;}
00136 
00142     template<class F>
00143     void mult(const Matrix<F>& src, Matrix<F>& dst,
00144         uint n = 0, uint m = 0) const;
00145 
00151     template<class F>
00152     void mult_T(const Matrix<F>& src, Matrix<F>& dst,
00153     uint n = 0, uint m = 0) const;
00154 
00164     template<class F>
00165     void mult_T(const F* src, F* dst, const uint s, const uint t) const;
00167     inline const concepts::Real& operator()(uint i, uint j) const {
00168       return m_[i*n_ + j];
00169     }
00171     inline uint n() const {return n_;}
00172 
00173   private:
00175     concepts::Real* m_;
00177     uint n_;
00178   };
00179 
00180   template<class F>
00181   void M000::mult(const Matrix<F>& src, Matrix<F>& dst, uint n, uint m) const {
00182     const F* sv = src.source();
00183     F* dv = dst.destination();
00184     const concepts::Real* mat = &(*this)(n, m);
00185 
00186     if (src.roworder()) {
00187       if (dst.roworder()) {
00188 
00189   for(uint i = 0; i < dst.nrow(); i++) {
00190     const concepts::Real* matrow = mat + i*n_;
00191     for(uint j = 0; j < dst.ncol(); j++) {
00192       *dv = 0.0;
00193       const F* svj = sv + j;
00194       for(uint k = 0; k < src.nrow(); k++) {
00195         *dv += *svj * matrow[k];  svj += src.ncol();
00196       }
00197       dv++;
00198     }
00199   } // for i
00200 
00201       } // if dst row order
00202       else {
00203 
00204   for(uint i = 0; i < dst.ncol(); i++) {
00205     for(uint j = 0; j < dst.nrow(); j++) {
00206       *dv = 0.0;
00207       const concepts::Real* matrow = mat + j*n_;
00208       const F* svi = sv + i;
00209       for(uint k = 0; k < src.nrow(); k++) {
00210         *dv += *svi * matrow[k];  svi += src.ncol();
00211       }
00212       dv++;
00213     }
00214   } // for i
00215 
00216       } // if dst col order
00217     } // if src row order
00218     else {
00219       if (dst.roworder()) {
00220 
00221   for(uint i = 0; i < dst.nrow(); i++) {
00222     const concepts::Real* matrow = mat + i*n_;
00223     for(uint j = 0; j < dst.ncol(); j++) {
00224       *dv = 0.0;
00225       const F* svj = sv + j*src.nrow();
00226       for(uint k = 0; k < src.nrow(); k++) {
00227         *dv += *svj++ * matrow[k];
00228       }
00229       dv++;
00230     }
00231   } // for i
00232 
00233       } // if dst row order
00234       else {
00235 
00236   for(uint i = 0; i < dst.ncol(); i++) {
00237     for(uint j = 0; j < dst.nrow(); j++) {
00238       *dv = 0.0;
00239       const concepts::Real* matrow = mat + j*n_;
00240       const F* svi = sv + i*src.nrow();
00241       for(uint k = 0; k < src.nrow(); k++) {
00242         *dv += *svi++ * matrow[k];
00243       }
00244       dv++;
00245     }
00246   } // for i
00247 
00248       } // if dst col order
00249     } // if src col order
00250   }
00251 
00252   template<class F>
00253   void M000::mult_T(const Matrix<F>& src, Matrix<F>& dst,
00254         uint n, uint m) const {
00255     const F* sv = src.source();
00256     F* dv = dst.destination();
00257     const concepts::Real* mat = &(*this)(m, n);
00258 
00259     if (src.roworder()) {
00260       if (dst.roworder()) {
00261 
00262   for(uint i = 0; i < dst.nrow(); i++) {
00263     for(uint j = 0; j < dst.ncol(); j++) {
00264       *dv = 0.0;
00265       const concepts::Real* matrow = mat + i;
00266       const F* svj = sv + j;
00267       for(uint k = 0; k < src.nrow(); k++) {
00268         *dv += *svj * *matrow;  svj += src.ncol();  matrow += n_;
00269       }
00270       dv++;
00271     }
00272   } // for i
00273 
00274       } // if dst row order
00275       else {
00276 
00277   for(uint i = 0; i < dst.ncol(); i++) {
00278     for(uint j = 0; j < dst.nrow(); j++) {
00279       *dv = 0.0;
00280       const concepts::Real* matrow = mat + j;
00281       const F* svi = sv + i;
00282       for(uint k = 0; k < src.nrow(); k++) {
00283         *dv += *svi * *matrow;  svi += src.ncol();  matrow += n_;
00284       }
00285       dv++;
00286     }
00287   } // for i
00288 
00289       } // if dst col order
00290     } // if src row order
00291     else {
00292       if (dst.roworder()) {
00293 
00294   for(uint i = 0; i < dst.nrow(); i++) {
00295     for(uint j = 0; j < dst.ncol(); j++) {
00296       *dv = 0.0;
00297       const concepts::Real* matrow = mat + i;
00298       const F* svj = sv + j*src.nrow();
00299       for(uint k = 0; k < src.nrow(); k++) {
00300         *dv += *svj++ * *matrow;  matrow += n_;
00301       }
00302       dv++;
00303     }
00304   } // for i
00305 
00306       } // if dst row order
00307       else {
00308 
00309   for(uint i = 0; i < dst.ncol(); i++) {
00310     for(uint j = 0; j < dst.nrow(); j++) {
00311       *dv = 0.0;
00312       const concepts::Real* matrow = mat + j;
00313       const F* svi = sv + i*src.nrow();
00314       for(uint k = 0; k < src.nrow(); k++) {
00315         *dv += *svi++ * *matrow;  matrow += n_;
00316       }
00317       dv++;
00318     }
00319   } // for i
00320 
00321       } // if dst col order
00322     } // if src col order
00323   }
00324 
00325   template<class F>
00326   void M000::mult_T(const F* src, F* dst, const uint s, const uint t) const {
00327     for(uint i = 0; i < t; i++) {
00328       for(uint j = 0; j < s; j++) {
00329   concepts::Real* mi = m_ + i;
00330   const F* sj = src + j;
00331   *dst = 0.0;
00332   for(uint k = 0; k < n_; k++, mi += n_, sj += s)  *dst += *sj * *mi;
00333   dst++;
00334       }
00335     }
00336   }
00337 
00338   // ************************************************************* Haar3d000 **
00339 
00343   template<class F = concepts::Real>
00344   class Haar3d000 : public Haar3dXXX<F> {
00345   public:
00359     Haar3d000(const concepts::Real3d& cntr, concepts::Real rd,
00360         const concepts::Real* m, uint n, uint idx[], uint idxn,
00361         concepts::Real sz, Haar3d000<F>* chld,
00362         const bem::Constant3d002<F>** elm, uint nelm);
00364     ~Haar3d000() {delete T_;  if (nelm_)  delete[] elm_;}
00365 
00367     Haar3d000<F>* child() const {return chld_;}
00369     Haar3d000<F>* link() const {return lnk_;}
00370     inline Haar3d000<F>*& link() {return lnk_;}
00372     const bem::Constant3d002<F>* element(uint j) const;
00374     inline uint nelement() const {return nelm_;}
00378     inline uint gamma() const {return gamma_;}
00379     inline uint& gamma() {return gamma_;}
00380 
00382     inline const concepts::TMatrixBase<F>& T() const {return *T_;}
00384     inline void replaceT(uint idx[], uint idxn);
00386     inline const M000& trafoM() const {return M_;}
00388     inline uint index() const {return idx_;}
00389 
00390   protected:
00392     std::ostream& info(std::ostream& os) const;
00393 
00394   private:
00396     M000 M_;
00398     const concepts::TIndex<F>* T_;
00400     concepts::Real sz_;
00402     Haar3d000* lnk_;
00404     Haar3d000* chld_;
00406     const bem::Constant3d002<F>** elm_;
00408     uint nelm_;
00410     uint gamma_;
00412     uint idx_;
00413 
00414     static uint index_;
00415   };
00416 
00417   template<class F>
00418   Haar3d000<F>::Haar3d000(const concepts::Real3d& cntr, concepts::Real rd,
00419         const concepts::Real* m, uint n,
00420         uint idx[], uint idxn, concepts::Real sz,
00421         Haar3d000<F>* chld,
00422         const bem::Constant3d002<F>** elm, uint nelm)
00423     : Haar3dXXX<F>(cntr, rd, sz), M_(m, n),
00424       lnk_(0), chld_(chld), nelm_(nelm), gamma_(1), idx_(index_++) {
00425 
00426     T_ = new concepts::TIndex<F>(idxn, idxn, idx);
00427 
00428     if (nelm) {
00429       elm_ = new const bem::Constant3d002<F>*[nelm_];
00430       std::memcpy(elm_, elm, nelm_*sizeof(elm[0]));
00431     }
00432     else elm_ = 0;
00433   }
00434 
00435   template<class F>
00436   const bem::Constant3d002<F>* Haar3d000<F>::element(uint j) const {
00437     return (j < nelm_) ? elm_[j] : (bem::Constant3d002<F>*)0;
00438   }
00439 
00440   template<class F>
00441   void Haar3d000<F>::replaceT(uint idx[], uint idxn) {
00442     delete T_;
00443     T_ = new concepts::TIndex<F>(idxn, idxn, idx);
00444   }
00445 
00446 } // namespace aglowav2
00447 
00448 #endif //aglowav2Element_hh

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