00001
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
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
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
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 }
00200
00201 }
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 }
00215
00216 }
00217 }
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 }
00232
00233 }
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 }
00247
00248 }
00249 }
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 }
00273
00274 }
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 }
00288
00289 }
00290 }
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 }
00305
00306 }
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 }
00320
00321 }
00322 }
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
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 }
00447
00448 #endif //aglowav2Element_hh