00001
00002
00003
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef _CHOMP_CUBES_CELLVAR_H_
00037 #define _CHOMP_CUBES_CELLVAR_H_
00038
00039 #include "chomp/system/config.h"
00040 #include "chomp/system/textfile.h"
00041 #include "chomp/cubes/pointset.h"
00042 #include "chomp/homology/chains.h"
00043 #include "chomp/struct/bitfield.h"
00044 #include "chomp/struct/integer.h"
00045 #include "chomp/struct/hashsets.h"
00046 #include "chomp/homology/gcomplex.h"
00047 #include "chomp/cubes/pointbas.h"
00048 #include "chomp/cubes/cubevar.h"
00049 #include "chomp/cubes/cellmain.h"
00050
00051 #include <iostream>
00052 #include <fstream>
00053 #include <cstdlib>
00054
00055 namespace chomp {
00056 namespace homology {
00057
00058
00059
00060
00061
00062
00067 template <class coordtype>
00068 class tCellVar
00069 {
00070 public:
00072 typedef coordtype CoordType;
00073
00075 static const int MaxDim =
00076 (tCubeVar<coordtype>::MaxDim < MaxBasDim) ?
00077 tCubeVar<coordtype>::MaxDim : MaxBasDim;
00078
00080 static const int MaxSpaceDim = tCubeVar<coordtype>::MaxDim;
00081
00083 typedef typename tCubeVar<coordtype>::PointBase PointBase;
00084
00086 tCellVar ();
00087
00089 tCellVar (const coordtype *c1, const coordtype *c2,
00090 int spcdim, int celldim = -1);
00091
00093 tCellVar (const tCubeVar<coordtype> &q1,
00094 const tCubeVar<coordtype> &q2);
00095
00098 tCellVar (const tCubeVar<coordtype> &q, int facedim);
00099
00101 explicit tCellVar (const tCubeVar<coordtype> &q);
00102
00105 tCellVar (const tCellVar<coordtype> &q, int offset, int ncoords);
00106
00108 tCellVar (const tCellVar<coordtype> &c);
00109
00111 tCellVar<coordtype> &operator = (const tCellVar<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 tCellVar<coordtype> &c1,
00154 const tCellVar<coordtype> &c2)
00155 {
00156 return ((c1. n == c2. n) && ((c1. n == 0) ||
00157 thesame (c1. tab, c2. tab, c1. spacedim ())));
00158 }
00159
00160 private:
00162 coordtype *tab;
00163
00167 int_t n;
00168
00170 void initialize (const coordtype *c1, const coordtype *c2,
00171 int spcdim, int celldim = -1);
00172
00173 };
00174
00175
00176
00177 template<class coordtype>
00178 int tCellVar<coordtype>::OutputBits = 0;
00179
00180
00181
00182 template <class coordtype>
00183 inline void tCellVar<coordtype>::initialize (const coordtype *c1,
00184 const coordtype *c2, int spcdim, int)
00185 {
00186
00187 if (spcdim <= 0)
00188 throw "Non-positive dimension of the space.";
00189 else if (spcdim >= MaxDim)
00190 throw "Too high dimension of a cell.";
00191
00192
00193 n = static_cast<int_t> (spcdim) << NumBits;
00194
00195
00196 tab = new coordtype [spcdim];
00197 if (!tab)
00198 throw "Not enough memory to create a cell.";
00199
00200
00201 PointBase::wrapcopy (tab, c1, spcdim);
00202
00203
00204 coordtype r [MaxDim];
00205 PointBase::wrapcopy (r, c2, spcdim);
00206
00207
00208 for (int i = 0; i < spcdim; ++ i)
00209 {
00210 if (tab [i] != r [i])
00211 n |= (static_cast<int_t> (1) << i);
00212 }
00213 return;
00214 }
00215
00216 template <class coordtype>
00217 inline tCellVar<coordtype>::tCellVar ()
00218 : tab (0), n (0)
00219 {
00220 return;
00221 }
00222
00223 template <class coordtype>
00224 inline tCellVar<coordtype>::tCellVar
00225 (const coordtype *c1, const coordtype *c2, int spcdim, int celldim)
00226 {
00227 initialize (c1, c2, spcdim, celldim);
00228 return;
00229 }
00230
00231 template <class coordtype>
00232 inline int tCellVar<coordtype>::dim () const
00233 {
00234 int count = 0;
00235 for (int i = 0; i < NumBits; ++ i)
00236 {
00237 if (n & (static_cast<int_t> (1) << i))
00238 ++ count;
00239 }
00240 return count;
00241 }
00242
00243 template <class coordtype>
00244 inline int tCellVar<coordtype>::spacedim () const
00245 {
00246 return static_cast<int> (n >> NumBits);
00247 }
00248
00249 template <class coordtype>
00250 inline tCellVar<coordtype>::tCellVar (const tCellVar<coordtype> &q,
00251 int offset, int ncoords)
00252 {
00253 int spcdim = static_cast<int> (q. n >> NumBits);
00254 if ((offset < 0) || (ncoords <= 0) || (offset + ncoords > spcdim))
00255 throw "Wrong cell projection requested.";
00256 coordtype right [MaxDim];
00257 q. rightcoord (right);
00258 initialize (q. tab + offset, right + offset, ncoords);
00259
00260
00261
00262
00263
00264
00265
00266 return;
00267 }
00268
00269 template <class coordtype>
00270 inline tCellVar<coordtype>::tCellVar (const tCellVar<coordtype> &q)
00271 {
00272 n = q. n;
00273 tab = new coordtype [spacedim ()];
00274 if (!tab)
00275 throw "Not enough memory to copy a cubical cell.";
00276 copycoord (tab, q. tab, spacedim ());
00277 return;
00278 }
00279
00280 template <class coordtype>
00281 inline tCellVar<coordtype> &tCellVar<coordtype>::operator =
00282 (const tCellVar<coordtype> &q)
00283 {
00284
00285 int d = q. spacedim ();
00286
00287
00288 if (d != spacedim ())
00289 {
00290 if (tab)
00291 delete [] tab;
00292 tab = new coordtype [d];
00293 if (!tab)
00294 throw "Not enough memory to copy a cubical cell.";
00295 }
00296
00297
00298 copycoord (tab, q. tab, d);
00299 n = q. n;
00300
00301 return *this;
00302 }
00303
00304 template <class coordtype>
00305 inline coordtype *tCellVar<coordtype>::leftcoord (coordtype *c) const
00306 {
00307 if (!c)
00308 throw "Null pointer to save left coordinates.";
00309 int d = spacedim ();
00310 for (int i = 0; i < d; ++ i)
00311 c [i] = tab [i];
00312 return c;
00313 }
00314
00315 template <class coordtype>
00316 inline coordtype *tCellVar<coordtype>::rightcoord (coordtype *c) const
00317 {
00318 if (!c)
00319 throw "Null pointer to save right coordinates.";
00320 int d = spacedim ();
00321 for (int i = 0; i < d; ++ i)
00322 {
00323 c [i] = tab [i];
00324 if (n & (static_cast<int_t> (1) << i))
00325 ++ (c [i]);
00326 }
00327 PointBase::wrapcoord (c, d);
00328 return c;
00329 }
00330
00331 template <class coordtype>
00332 inline int_t tCellVar<coordtype>::hashkey1 () const
00333 {
00334 switch (spacedim ())
00335 {
00336 case 0:
00337 return 0;
00338 case 1:
00339 return (static_cast<int_t> (tab [0]) << 12) ^ n;
00340 case 2:
00341 return (((static_cast<int_t> (tab [0])) << 18) +
00342 ((static_cast<int_t> (tab [1])) << 6)) ^ n;
00343 default:
00344 return (((static_cast<int_t> (tab [0])) << 18) +
00345 ((static_cast<int_t> (tab [1])) << 6) +
00346 ((static_cast<int_t> (tab [2])) >> 6)) ^ n;
00347 }
00348 }
00349
00350 template <class coordtype>
00351 inline int_t tCellVar<coordtype>::hashkey2 () const
00352 {
00353 int d = spacedim ();
00354 switch (d)
00355 {
00356 case 0:
00357 return 0;
00358 case 1:
00359 return (static_cast<int_t> (tab [0]) << 3) ^ (n << 5);
00360 case 2:
00361 return ((static_cast<int_t> (tab [0]) >> 1) +
00362 (static_cast<int_t> (tab [1]) << 13)) ^ (n << 5);
00363 default:
00364 return (((static_cast<int_t> (tab [d - 1])) << 20) +
00365 ((static_cast<int_t> (tab [d - 2])) << 9) +
00366 ((static_cast<int_t> (tab [d - 3])) >> 1)) ^
00367 (n << 5);
00368 }
00369 }
00370
00371 template <class coordtype>
00372 const char *tCellVar<coordtype>::name ()
00373 {
00374 return "cubical cell";
00375 }
00376
00377 template <class coordtype>
00378 const char *tCellVar<coordtype>::pluralname ()
00379 {
00380 return "cubical cells";
00381 }
00382
00383
00384
00385 template <class coordtype>
00386 inline tCellVar<coordtype>::tCellVar
00387 (const tCubeVar<coordtype> &q1, const tCubeVar<coordtype> &q2)
00388 {
00389
00390 coordtype left [MaxDim];
00391 coordtype right [MaxDim];
00392
00393
00394 coordtype c1 [MaxDim];
00395 q1. coord (c1);
00396 coordtype c2 [MaxDim];
00397 q2. coord (c2);
00398
00399
00400 int spcdim = q1. dim ();
00401 if (spcdim != q2. dim ())
00402 throw "Trying to intersect cubes of different dimension.";
00403
00404
00405
00406 int celldim = 0;
00407 const coordtype *wrap = PointBase::getwrapping (spcdim);
00408 for (int i = 0; i < spcdim; ++ i)
00409 {
00410 if (c1 [i] == c2 [i])
00411 {
00412 left [i] = c1 [i];
00413 right [i] = c1 [i];
00414 ++ right [i];
00415 ++ celldim;
00416 }
00417 else if ((c1 [i] - c2 [i] == -1) || (wrap && wrap [i] &&
00418 (c1 [i] - c2 [i] == wrap [i] - 1)))
00419 {
00420 left [i] = c2 [i];
00421 right [i] = c2 [i];
00422 }
00423 else if ((c1 [i] - c2 [i] == 1) || (wrap && wrap [i] &&
00424 (c1 [i] - c2 [i] == -wrap [i] + 1)))
00425 {
00426 left [i] = c1 [i];
00427 right [i] = c1 [i];
00428 }
00429 else
00430 throw "The cubes do not intersect.";
00431 }
00432
00433
00434 initialize (left, right, spcdim, celldim);
00435
00436 return;
00437 }
00438
00439 template <class coordtype>
00440 inline tCellVar<coordtype>::tCellVar (const tCubeVar<coordtype> &q)
00441
00442
00443 {
00444
00445 const coordtype *left = q. tab + 1;
00446
00447
00448 int d = q. dim ();
00449
00450
00451 coordtype right [MaxDim];
00452
00453
00454 for (int i = 0; i < d; ++ i)
00455 right [i] = left [i] + 1;
00456
00457
00458 initialize (left, right, d, d);
00459 return;
00460 }
00461
00462 template <class coordtype>
00463 inline tCellVar<coordtype>::tCellVar (const tCubeVar<coordtype> &q,
00464 int facedim)
00465
00466
00467 {
00468
00469 const coordtype *left = q. tab + 1;
00470
00471
00472 coordtype right [MaxDim];
00473
00474
00475 int d = q. dim ();
00476
00477
00478 for (int i = 0; i < d; ++ i)
00479 right [i] = left [i] + ((i < facedim) ? 1 : 0);
00480
00481
00482 initialize (left, right, d, facedim);
00483 return;
00484 }
00485
00486
00487
00489 template <class coordtype>
00490 inline int operator != (const tCellVar<coordtype> &c1,
00491 const tCellVar<coordtype> &c2)
00492 {
00493 return !(c1 == c2);
00494 }
00495
00496
00497
00499 template <class coordtype>
00500 inline tCellVar<coordtype> operator *
00501 (const tCellVar<coordtype> &c1,
00502 const tCellVar<coordtype> &c2)
00503 {
00504
00505 int d1 = c1. spacedim (), d2 = c2. spacedim ();
00506 if (d1 + d2 >= tCellVar<coordtype>::MaxDim)
00507 throw "Too high dimension of a Cartesian product of cells.";
00508
00509
00510 coordtype left [tCellVar<coordtype>::MaxDim];
00511 coordtype right [tCellVar<coordtype>::MaxDim];
00512
00513
00514 c1. leftcoord (left);
00515 c1. rightcoord (right);
00516
00517
00518 c2. leftcoord (left + d1);
00519 c2. rightcoord (right + d1);
00520
00521
00522 return tCellVar<coordtype> (left, right, d1 + d2,
00523 c1. dim () + c2. dim ());
00524 }
00525
00527 template <class coordtype>
00528 inline std::ostream &operator << (std::ostream &out,
00529 const tCellVar<coordtype> &c)
00530 {
00531 return WriteCubicalCell (out, c);
00532 }
00533
00535 template <class coordtype>
00536 inline std::istream &operator >> (std::istream &in,
00537 tCellVar<coordtype> &c)
00538 {
00539 return ReadCubicalCell (in, c);
00540 }
00541
00542
00543
00545 template <class coordtype>
00546 inline tCellVar<coordtype> boundarycell (const tCellVar<coordtype> &q,
00547 int i, bool onlyexisting)
00548 {
00549 return CubicalBoundaryCell (q, i, onlyexisting);
00550 }
00551
00553 template <class coordtype>
00554 inline tCellVar<coordtype> boundarycell (const tCellVar<coordtype> &q,
00555 int i)
00556 {
00557 return CubicalBoundaryCell (q, i);
00558 }
00559
00561 template <class coordtype>
00562 inline int boundarylength (const tCellVar<coordtype> &q)
00563 {
00564 return CubicalBoundaryLength (q);
00565 }
00566
00568 template <class coordtype>
00569 inline int boundarycoef (const tCellVar<coordtype> &q, int i)
00570 {
00571 return CubicalBoundaryCoef (q, i);
00572 }
00573
00574
00575 }
00576 }
00577
00578 #endif // _CHOMP_CUBES_CELLVAR_H_
00579
00581