00001
00002
00003
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef _CHOMP_CUBES_CELLBASE_H_
00038 #define _CHOMP_CUBES_CELLBASE_H_
00039
00040 #include "chomp/system/config.h"
00041 #include "chomp/system/textfile.h"
00042 #include "chomp/cubes/pointset.h"
00043 #include "chomp/homology/chains.h"
00044 #include "chomp/struct/bitfield.h"
00045 #include "chomp/struct/integer.h"
00046 #include "chomp/struct/hashsets.h"
00047 #include "chomp/homology/gcomplex.h"
00048 #include "chomp/cubes/pointbas.h"
00049 #include "chomp/cubes/cubebase.h"
00050 #include "chomp/cubes/cellmain.h"
00051
00052 #include <iostream>
00053 #include <fstream>
00054 #include <cstdlib>
00055
00056 namespace chomp {
00057 namespace homology {
00058
00059
00060
00061
00062
00063
00068 template <class coordtype>
00069 class tCellBase
00070 {
00071 public:
00073 typedef coordtype CoordType;
00074
00076 static const int MaxDim = tCubeBase<coordtype>::MaxDim;
00077
00079 static const int MaxSpaceDim = tCubeBase<coordtype>::MaxDim;
00080
00082 typedef typename tCubeBase<coordtype>::PointBase PointBase;
00083
00085 tCellBase ();
00086
00088 tCellBase (const coordtype *c1, const coordtype *c2,
00089 int spcdim, int celldim = -1);
00090
00092 tCellBase (const tCubeBase<coordtype> &q1,
00093 const tCubeBase<coordtype> &q2);
00094
00097 tCellBase (const tCubeBase<coordtype> &q, int facedim);
00098
00100 explicit tCellBase (const tCubeBase<coordtype> &q);
00101
00104 tCellBase (const tCellBase<coordtype> &q, int offset, int ncoords);
00105
00107 tCellBase (const tCellBase<coordtype> &c);
00108
00110 tCellBase<coordtype> &operator =
00111 (const tCellBase<coordtype> &c);
00112
00114 int dim () const;
00115
00117 int spacedim () const;
00118
00120 coordtype *leftcoord (coordtype *c) const;
00121
00123 coordtype *rightcoord (coordtype *c) const;
00124
00126 int_t hashkey1 () const;
00127
00129 int_t hashkey2 () const;
00130
00132 static const char *name ();
00133
00135 static const char *pluralname ();
00136
00141 enum OutputBitValues
00142 {
00143 BitProduct = 0x01,
00144 BitSpace = 0x02
00145 };
00146
00148 static int OutputBits;
00149
00150
00151
00153 friend inline int operator == (const tCellBase<coordtype> &c1,
00154 const tCellBase<coordtype> &c2)
00155 {
00156 return (c1. n1 == c2. n1) && (c1. n2 == c2. n2);
00157 }
00158
00159 private:
00161 int_t num1 () const;
00162
00164 int_t num2 () const;
00165
00168 int_t n1;
00169
00172 int_t n2;
00173
00175 void initialize (const coordtype *c1, const coordtype *c2,
00176 int spcdim, int celldim = -1);
00177
00178 };
00179
00180
00181
00182 template<class coordtype>
00183 int tCellBase<coordtype>::OutputBits = 0;
00184
00185
00186
00187 template <class coordtype>
00188 inline int_t tCellBase<coordtype>::num1 () const
00189 {
00190 return (n1 & NumMask);
00191 }
00192
00193 template <class coordtype>
00194 inline int_t tCellBase<coordtype>::num2 () const
00195 {
00196 return (n2 & NumMask);
00197 }
00198
00199 template <class coordtype>
00200 inline void tCellBase<coordtype>::initialize (const coordtype *c1,
00201 const coordtype *c2, int spcdim, int celldim)
00202 {
00203
00204 if (spcdim <= 0)
00205 throw "Non-positive dimension of the space.";
00206 else if (spcdim >= MaxDim)
00207 throw "Too high dimension of a cell.";
00208
00209
00210 n1 = PointBase::number (c1, spcdim);
00211 if (n1 < 0)
00212 throw "Negative number of the left vertex.";
00213
00214
00215 n2 = PointBase::number (c2, spcdim);
00216 if (n2 < 0)
00217 throw "Negative number of the right vertex.";
00218
00219
00220 if (celldim < 0)
00221 {
00222 celldim = 0;
00223 c1 = PointBase::coord (n1, spcdim);
00224 c2 = PointBase::coord (n2, spcdim);
00225 for (int i = 0; i < spcdim; ++ i)
00226 {
00227 if (c2 [i] != c1 [i])
00228 ++ celldim;
00229 }
00230 }
00231
00232
00233 n1 |= (static_cast<int_t> (spcdim) << NumBits);
00234 n2 |= (static_cast<int_t> (celldim) << NumBits);
00235 return;
00236 }
00237
00238
00239
00240 template <class coordtype>
00241 inline tCellBase<coordtype>::tCellBase ()
00242 : n1 (0), n2 (0)
00243 {
00244 return;
00245 }
00246
00247 template <class coordtype>
00248 inline tCellBase<coordtype>::tCellBase
00249 (const coordtype *c1, const coordtype *c2, int spcdim, int celldim)
00250 {
00251 initialize (c1, c2, spcdim, celldim);
00252 return;
00253 }
00254
00255 template <class coordtype>
00256 inline tCellBase<coordtype>::tCellBase
00257 (const tCubeBase<coordtype> &q1, const tCubeBase<coordtype> &q2)
00258 {
00259
00260 int spcdim = q1. dim ();
00261 if (spcdim != q2. dim ())
00262 throw "Trying to intersect cubes of different dimension.";
00263
00264
00265 coordtype c1 [MaxDim];
00266 q1. coord (c1);
00267 coordtype c2 [MaxDim];
00268 q2. coord (c2);
00269
00270
00271 coordtype left [MaxDim];
00272 coordtype right [MaxDim];
00273
00274
00275 int celldim = CommonCell (left, right, c1, c2, spcdim,
00276 PointBase::getwrapping (spcdim));
00277
00278
00279 initialize (left, right, spcdim, celldim);
00280
00281 return;
00282 }
00283
00284 template <class coordtype>
00285 inline tCellBase<coordtype>::tCellBase (const tCubeBase<coordtype> &q,
00286 int facedim)
00287 : n1 (q. n)
00288 {
00289
00290 int spcdim = static_cast<int> (n1 >> NumBits);
00291 if (facedim < 0)
00292 throw "Negative dimension of a face requested.";
00293 if (facedim > spcdim)
00294 throw "Too high dimension of a face requested.";
00295
00296
00297 const coordtype *c1 = PointBase::coord (num1 (), spcdim);
00298 coordtype c2 [MaxDim];
00299 for (int i = 0; i < spcdim; ++ i)
00300 c2 [i] = c1 [i] + ((i < facedim) ? 1 : 0);
00301
00302
00303 n2 = PointBase::number (c2, spcdim) |
00304 (static_cast<int_t> (facedim) << NumBits);
00305 return;
00306 }
00307
00308 template <class coordtype>
00309 inline tCellBase<coordtype>::tCellBase (const tCubeBase<coordtype> &q)
00310 : n1 (q. n)
00311 {
00312
00313 int spcdim = static_cast<int> (n1 >> NumBits);
00314 const coordtype *c1 = PointBase::coord (num1 (), spcdim);
00315 coordtype c2 [MaxDim];
00316 for (int i = 0; i < spcdim; ++ i)
00317 c2 [i] = c1 [i] + 1;
00318
00319
00320 n2 = PointBase::number (c2, spcdim) |
00321 (static_cast<int_t> (spcdim) << NumBits);
00322 return;
00323 }
00324
00325 template <class coordtype>
00326 inline tCellBase<coordtype>::tCellBase (const tCellBase<coordtype> &q,
00327 int offset, int ncoords)
00328 {
00329 int spcdim = static_cast<int> (q. n1 >> NumBits);
00330 if ((offset < 0) || (ncoords <= 0) || (offset + ncoords > spcdim))
00331 throw "Wrong cell projection requested.";
00332 const coordtype *c1 = PointBase::coord (q. n1 & NumMask, spcdim);
00333 const coordtype *c2 = PointBase::coord (q. n2 & NumMask, spcdim);
00334 initialize (c1 + offset, c2 + offset, ncoords);
00335 return;
00336 }
00337
00338 template <class coordtype>
00339 inline tCellBase<coordtype>::tCellBase (const tCellBase<coordtype> &q)
00340 : n1 (q. n1), n2 (q. n2)
00341 {
00342 return;
00343 }
00344
00345 template <class coordtype>
00346 inline tCellBase<coordtype> &tCellBase<coordtype>::operator =
00347 (const tCellBase<coordtype> &q)
00348 {
00349 n1 = q. n1;
00350 n2 = q. n2;
00351 return *this;
00352 }
00353
00354 template <class coordtype>
00355 inline int tCellBase<coordtype>::dim () const
00356 {
00357 return static_cast<int> (n2 >> NumBits);
00358 }
00359
00360 template <class coordtype>
00361 inline int tCellBase<coordtype>::spacedim () const
00362 {
00363 return (n1 >> NumBits);
00364 }
00365
00366 template <class coordtype>
00367 inline coordtype *tCellBase<coordtype>::leftcoord (coordtype *c) const
00368 {
00369 const coordtype *leftc = PointBase::coord (num1 (), spacedim ());
00370 if (!c)
00371 throw "Null pointer to save left coordinates.";
00372 copycoord (c, leftc, spacedim ());
00373 return c;
00374 }
00375
00376 template <class coordtype>
00377 inline coordtype *tCellBase<coordtype>::rightcoord (coordtype *c) const
00378 {
00379 const coordtype *rightc = PointBase::coord (num2 (), spacedim ());
00380 if (!c)
00381 throw "Null pointer to save right coordinates.";
00382 copycoord (c, rightc, spacedim ());
00383 return c;
00384 }
00385
00386 template <class coordtype>
00387 inline int_t tCellBase<coordtype>::hashkey1 () const
00388 {
00389 return ((n1 ^ 0x55555555u) << 17) ^ ((n1 ^ 0xAAAAAAAAu) << 7) ^
00390 ((n2 ^ 0xAAAAAAAAu) >> 7);
00391 }
00392
00393 template <class coordtype>
00394 inline int_t tCellBase<coordtype>::hashkey2 () const
00395 {
00396 return ((n2 ^ 0xAAAAAAAAu) << 21) ^ ((n2 ^ 0x55555555u) << 10) ^
00397 ((n1 ^ 0x55555555u) >> 9);
00398 }
00399
00400 template <class coordtype>
00401 const char *tCellBase<coordtype>::name ()
00402 {
00403 return "cubical cell";
00404 }
00405
00406 template <class coordtype>
00407 const char *tCellBase<coordtype>::pluralname ()
00408 {
00409 return "cubical cells";
00410 }
00411
00412
00413
00415 template <class coordtype>
00416 inline int operator != (const tCellBase<coordtype> &c1,
00417 const tCellBase<coordtype> &c2)
00418 {
00419 return !(c1 == c2);
00420 }
00421
00422
00423
00425 template <class coordtype>
00426 inline tCellBase<coordtype> operator *
00427 (const tCellBase<coordtype> &c1,
00428 const tCellBase<coordtype> &c2)
00429 {
00430
00431 int d1 = c1. spacedim (), d2 = c2. spacedim ();
00432 if (d1 + d2 >= tCellBase<coordtype>::MaxDim)
00433 throw "Too high dimension of a Cartesian product of cells.";
00434
00435
00436 coordtype left [tCellBase<coordtype>::MaxDim];
00437 coordtype right [tCellBase<coordtype>::MaxDim];
00438
00439
00440 c1. leftcoord (left);
00441 c1. rightcoord (right);
00442
00443
00444 c2. leftcoord (left + d1);
00445 c2. rightcoord (right + d1);
00446
00447
00448 return tCellBase<coordtype> (left, right, d1 + d2,
00449 c1. dim () + c2. dim ());
00450 }
00451
00453 template <class coordtype>
00454 inline std::ostream &operator << (std::ostream &out,
00455 const tCellBase<coordtype> &c)
00456 {
00457 return WriteCubicalCell (out, c);
00458 }
00459
00461 template <class coordtype>
00462 inline std::istream &operator >> (std::istream &in,
00463 tCellBase<coordtype> &c)
00464 {
00465 return ReadCubicalCell (in, c);
00466 }
00467
00468
00469
00473 template <class coordtype>
00474 inline tCellBase<coordtype> boundarycell (const tCellBase<coordtype> &q,
00475 int i, bool onlyexisting)
00476 {
00477 return CubicalBoundaryCell (q, i, onlyexisting);
00478 }
00479
00481 template <class coordtype>
00482 inline tCellBase<coordtype> boundarycell (const tCellBase<coordtype> &q,
00483 int i)
00484 {
00485 return CubicalBoundaryCell (q, i);
00486 }
00487
00489 template <class coordtype>
00490 inline int boundarylength (const tCellBase<coordtype> &q)
00491 {
00492 return CubicalBoundaryLength (q);
00493 }
00494
00496 template <class coordtype>
00497 inline int boundarycoef (const tCellBase<coordtype> &q, int i)
00498 {
00499 return CubicalBoundaryCoef (q, i);
00500 }
00501
00502
00503 }
00504 }
00505
00506 #endif // _CHOMP_CUBES_CELLBASE_H_
00507
00509