OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
octreelocalizert.h
Go to the documentation of this file.
1 /*
2  *
3  * ##### ##### ###### ###### ### ###
4  * ## ## ## ## ## ## ## ### ##
5  * ## ## ## ## #### #### ## # ##
6  * ## ## ## ## ## ## ## ##
7  * ## ## ## ## ## ## ## ##
8  * ##### ##### ## ###### ## ##
9  *
10  *
11  * OOFEM : Object Oriented Finite Element Code
12  *
13  * Copyright (C) 1993 - 2013 Borek Patzak
14  *
15  *
16  *
17  * Czech Technical University, Faculty of Civil Engineering,
18  * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19  *
20  * This library is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU Lesser General Public
22  * License as published by the Free Software Foundation; either
23  * version 2.1 of the License, or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28  * Lesser General Public License for more details.
29  *
30  * You should have received a copy of the GNU Lesser General Public
31  * License along with this library; if not, write to the Free Software
32  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33  */
34 
35 // **************************************
36 // *** CLASS OCTREE SPATIAL LOCALIZER ***
37 // **************************************
38 // general Octree localizer - using template
39 
40 #ifndef octreelocalizert_h
41 #define octreelocalizert_h
42 
43 #include "spatiallocalizer.h"
44 #include "octreelocalizer.h"
45 #include "delaunaytriangle.h"
46 #include "dofmanager.h"
47 #include "node.h"
48 #include "element.h"
49 #include "mathfem.h"
50 #include "timer.h"
51 
52 #include <set>
53 #include <list>
54 
55 namespace oofem {
56 class Domain;
57 class Element;
58 class TimeStep;
59 class DofManager;
60 class IntArray;
61 
62 template< class T >class OctreeSpatialLocalizerT;
63 
64 
65 #define TEMPLATED_OCTREE_MAX_NODES_LIMIT 800
66 
67 #define TEMPLATED_OCTREE_MAX_DEPTH 8
68 
69 //#define TEMPLATED_OCTREE_DEBUG
70 
73 
80 {
81 protected:
85  double size;
88 
89 public:
91  BoundingBox() : spatialMask(3) { }
92 
95 
97  void setOrigin(FloatArray &coords)
98  {
99  origin.resize( coords.giveSize() );
100  for ( int i = 1; i <= coords.giveSize(); i++ ) {
101  origin.at(i) = coords.at(i);
102  }
103  }
104 
106  void setSize(double s) { size = s; }
108  void setMask(int i, int mask) { spatialMask.at(i) = mask; }
113  void giveOrigin(FloatArray &answer) { answer = this->origin; }
115  double giveSize() { return size; }
120  void giveMask(IntArray &answer) { answer = this->spatialMask; }
124  void init (FloatArray& origin, double size, IntArray &mask)
125  {
126  this->origin = origin;
127  this->size = size;
128  this->spatialMask = mask;
129  }
130  bool contains(const FloatArray& coords) const
131  {
132  for ( int i = 1; i <= coords.giveSize(); i++ ) {
133  if ( spatialMask.at(i) ) {
134  if ( coords.at(i) < this->origin.at(i) ) {
135  return 0;
136  }
137 
138  if ( coords.at(i) > ( this->origin.at(i) + this->size ) ) {
139  return 0;
140  }
141  }
142  }
143 
144  return 1;
145  }
146 };
147 
153 template< class T >
155 {
156 public:
159  typedef typename std :: list< T > :: iterator listIteratorType;
160 
161 protected:
163  LocalizerPtrType localizer;
165  CellPtrType parent;
167  CellPtrType child [ 2 ] [ 2 ] [ 2 ];
171  double size;
172 
174  std :: list< T > *dataList;
175 
176 public:
177 
179  OctantRecT(LocalizerPtrType loc, CellPtrType parent, FloatArray &origin, double size)
180  {
181  this->localizer = loc;
182  this->parent = parent;
183  this->origin = origin;
184  this->size = size;
185  this->dataList = NULL;
186 
187 
188  for ( int i = 0; i <= 1; i++ ) {
189  for ( int j = 0; j <= 1; j++ ) {
190  for ( int k = 0; k <= 1; k++ ) {
191  this->child [ i ] [ j ] [ k ] = NULL;
192  }
193  }
194  }
195  }
198  {
199  for ( int i = 0; i <= 1; i++ ) {
200  for ( int j = 0; j <= 1; j++ ) {
201  for ( int k = 0; k <= 1; k++ ) {
202  if ( this->child [ i ] [ j ] [ k ] ) {
203  delete this->child [ i ] [ j ] [ k ];
204  }
205  }
206  }
207  }
208 
209  if ( dataList ) {
210  delete dataList;
211  }
212  }
213 
215  CellPtrType giveParent() { return this->parent; }
220  void giveOrigin(FloatArray &answer) { answer = this->origin; }
222  double giveSize() { return this->size; }
227  int containsPoint(const FloatArray &coords) {
228  for ( int i = 1; i <= coords.giveSize(); i++ ) {
229  if ( localizer->giveOctreeMaskValue(i) ) {
230  if ( coords.at(i) < this->origin.at(i) ) {
231  return 0;
232  }
233 
234  if ( coords.at(i) > ( this->origin.at(i) + this->size ) ) {
235  return 0;
236  }
237  }
238  }
239 
240  return 1;
241  }
249  CellPtrType giveChild(int xi, int yi, int zi) {
250  if ( ( xi >= 0 ) && ( xi < 2 ) && ( yi >= 0 ) && ( yi < 2 ) && ( zi >= 0 ) && ( zi < 2 ) ) {
251  return this->child [ xi ] [ yi ] [ zi ];
252  } else {
253  OOFEM_ERROR("OctantRecT::giveChild invalid child index (%d,%d,%d)", xi, yi, zi);
254  }
255  return NULL;
256  }
257 
268  int giveChildContainingPoint(CellPtrType *child, const FloatArray &coords) {
269  IntArray ind(3);
270  if ( this->containsPoint(coords) ) {
271  if ( this->isTerminalOctant() ) {
272  * child = NULL;
273  return -1;
274  }
275 
276  for ( int i = 1; i <= coords.giveSize(); i++ ) {
277  if ( localizer->giveOctreeMaskValue(i) && ( coords.at(i) > ( this->origin.at(i) + this->size / 2. ) ) ) {
278  ind.at(i) = 1;
279  } else {
280  ind.at(i) = 0;
281  }
282  }
283 
284  * child = this->child [ ind.at(1) ] [ ind.at(2) ] [ ind.at(3) ];
285  return 1;
286  } else {
287  * child = NULL;
288  return -2;
289  }
290  }
291 
294  {
295  if ( this->child [ 0 ] [ 0 ] [ 0 ] ) {
296  return 0;
297  }
298 
299  return 1;
300  }
301 
307  int divideLocally(int level, const IntArray &octantMask)
308  {
309  int i, j, k, result = 1;
310 
311  if ( this->isTerminalOctant() ) {
312  // create corresponding child octants
313  int i, j, k;
314  FloatArray childOrigin(3);
315 
316  for ( i = 0; i <= octantMask.at(1); i++ ) {
317  for ( j = 0; j <= octantMask.at(2); j++ ) {
318  for ( k = 0; k <= octantMask.at(3); k++ ) {
319  childOrigin.at(1) = this->origin.at(1) + i * ( this->size / 2. );
320  childOrigin.at(2) = this->origin.at(2) + j * ( this->size / 2. );
321  childOrigin.at(3) = this->origin.at(3) + k * ( this->size / 2. );
322 
323  this->child [ i ] [ j ] [ k ] = new OctantRecT(localizer, this, childOrigin, this->size / 2.0);
324  }
325  }
326  }
327  }
328 
329  int newLevel = level - 1;
330  if ( newLevel > 0 ) {
331  // propagate message to childs recursivelly with level param decreased
332  for ( i = 0; i <= octantMask.at(1); i++ ) {
333  for ( j = 0; j <= octantMask.at(2); j++ ) {
334  for ( k = 0; k <= octantMask.at(3); k++ ) {
335  if ( this->child [ i ] [ j ] [ k ] ) {
336  result &= this->child [ i ] [ j ] [ k ]->divideLocally(newLevel, octantMask);
337  }
338  }
339  }
340  }
341  }
342 
343  return result;
344  }
345 
352  {
353  int i, test = 0;
354  double BBXSize = testedBBX.giveSize();
355  FloatArray BBXOrigin;
356  testedBBX.giveOrigin(BBXOrigin);
357  int BBXOriginInside = this->containsPoint(BBXOrigin);
358  if ( BBXOriginInside ) {
359  for ( i = 1; i <= 3; i++ ) {
360  if ( localizer->giveOctreeMaskValue(i) ) {
361  if ( this->size > ( BBXSize + ( BBXOrigin.at(i) - this->origin.at(i) ) ) ) {
362  test = 1;
363  }
364  }
365  }
366 
367  if ( test ) {
369  } else {
371  }
372  } else {
373  for ( i = 1; i <= 3; i++ ) {
374  if ( localizer->giveOctreeMaskValue(i) ) {
375  if ( BBXOrigin.at(i) > ( this->size + this->origin.at(i) ) ) {
377  } else {
378  if ( BBXOrigin.at(i) + BBXSize > this->origin.at(i) ) {
380  } else {
382  }
383  }
384  }
385  }
386  }
388  }
389 
396  boundingSphereStatus testBoundingSphere(const FloatArray &coords, double radius)
397  {
398  int i, test = 1, nsd, size = coords.giveSize();
399  double dist;
400 
401  nsd = localizer->giveOctreeMaskValue(1) + localizer->giveOctreeMaskValue(2) + localizer->giveOctreeMaskValue(3);
402 
403  FloatArray cellCenter = this->origin;
404  double cellRadius = sqrt( nsd * ( this->size / 2.0 ) * ( this->size / 2. ) );
405  for ( i = 1; i < 4; i++ ) {
406  cellCenter.at(i) += this->size / 2.0;
407  }
408 
409  for ( i = 1, dist = 0.0; i <= size; i++ ) {
410  if ( localizer->giveOctreeMaskValue(i) ) {
411  dist += ( cellCenter.at(i) - coords.at(i) ) * ( cellCenter.at(i) - coords.at(i) );
412  }
413  }
414 
415  dist = sqrt(dist);
416  if ( dist > ( cellRadius + radius ) ) {
417  return SphereOutsideCell;
418  }
419 
420  int centerInside = this->containsPoint(coords);
421  if ( centerInside ) { // test if whole bsphere inside
422  for ( i = 1; i <= size; i++ ) {
423  if ( localizer->giveOctreeMaskValue(i) ) {
424  if ( ( this->origin.at(i) > ( coords.at(i) - radius ) ) || ( ( this->origin.at(i) + this->size ) < ( coords.at(i) + radius ) ) ) {
425  test = 0;
426  }
427  }
428  }
429 
430  if ( test ) {
431  return SphereInsideCell;
432  } else {
433  return SphereContainsCell;
434  }
435  } else { // BSphere center not inside cell, but may hit cell
436  // test if bounding sphere hits boundary surface
437  int inBounds = 1;
438  for ( i = 1; i <= size; i++ ) {
439  if ( localizer->giveOctreeMaskValue(i) && ( fabs( cellCenter.at(i) - coords.at(i) ) > ( this->size / 2. + radius ) ) ) {
440  inBounds = 0;
441  }
442  }
443 
444  if ( inBounds ) {
445  return SphereContainsCell;
446  }
447  }
448 
449  return SphereOutsideCell;
450  }
451 
452 
454  std :: list< T > *giveDataList() {
455  if ( dataList == NULL ) {
456  dataList = new std :: list< T >;
457  }
458 
459  return dataList;
460  }
461 
463  void deleteDataList() {
464  if ( dataList ) {
465  delete dataList;
466  dataList = NULL;
467  }
468  }
469 
471  listIteratorType addMember(T &member)
472  {
473  this->giveDataList()->push_front(member);
474  return this->giveDataList()->begin();
475  }
476 
478  void removeMember(T &member) { this->giveDataList()->remove(member); }
479 
480  friend class OctreeSpatialLocalizerT< T >;
481 };
482 
488 template< class T >
489 class LocalInsertionData
490 {
491 public:
495  typedef typename std :: list< T > :: iterator listIteratorType;
496 
500  listIteratorType posInCellDataList;
501 };
502 
503 
504 
510 template< class T >class SL_Insertion_Functor
511 {
512 protected:
513  typedef typename std :: list< T > :: iterator listIteratorType;
514 
515 public:
517  virtual bool evaluate(T &member, OctantRecT< T > *cell) = 0;
519  virtual void registerInsertion(T &member, LocalInsertionData< T >LIdata) = 0;
521  virtual std :: list< LocalInsertionData< T > > *giveInsertionList(T &member) = 0;
522 };
523 
524 
530 class InsertNode : public SL_Insertion_Functor< int >
531 {
532 protected:
534 
535 public:
538  domain = d;
539  }
542 
549  bool evaluate(int &nodeNr, OctantRecT< int > *cell)
550  {
551  FloatArray coords(3);
552  for ( int i = 1; i <= 3; i++ ) {
553  coords.at(i) = this->domain->giveNode(nodeNr)->giveCoordinate(i);
554  }
555 
556  if ( cell->containsPoint(coords) ) {
557  return true;
558  } else {
559  return false;
560  }
561  };
562 
563  void registerInsertion(int &nodeNr, LocalInsertionData< int >LIdata) { }
564 
565  std :: list< LocalInsertionData< int > > *giveInsertionList(int &nodeNr)
566  {
567  return NULL;
568  }
569 };
570 
576 class InsertTriangleBasedOnCircumcircle : public SL_Insertion_Functor< DelaunayTriangle * >
577 {
578 protected:
580 
581 public:
584  domain = d;
585  }
588 
596  {
597  double radius = DTptr->giveCircumRadius();
598  FloatArray centerCoords(3);
599  centerCoords.at(1) = DTptr->giveXCenterCoordinate();
600  centerCoords.at(2) = DTptr->giveYCenterCoordinate();
601  centerCoords.at(3) = 0.0;
602 
603  if ( cell->testBoundingSphere(centerCoords, radius) == SphereOutsideCell ) {
604  return false;
605  } else {
606  return true;
607  }
608  }
610  {
611  ( TEptr->giveListOfCellsAndPosition() )->push_back(LIdata);
612  }
613  std :: list< LocalInsertionData< DelaunayTriangle * > > *giveInsertionList(DelaunayTriangle * &DTptr)
614  {
615  return DTptr->giveListOfCellsAndPosition();
616  }
617 };
618 
624 template< class T >class SL_Evaluation_Functor
625 {
626 public:
628  virtual bool evaluate(T &obj) = 0;
630  virtual void giveStartingPosition(FloatArray &answer) = 0;
632  virtual void giveResult(std :: list< T > &answer) = 0;
633 
636  virtual bool isBBXStage1Defined(BoundingBox &BBXStage1) = 0;
637 
641  virtual bool isBBXStage2Defined(BoundingBox &BBXStage2) = 0;
642 };
643 
644 
650 class ClosestNode : public SL_Evaluation_Functor< int >
651 {
652 protected:
655  int CNindex;
657  bool initFlag;
658 
659  std :: list< int >closestNodeIndices;
660 
661 public:
668  initFlag = false;
669  startingPosition = pos;
670  domain = d;
671  }
674 
680  {
681  position = * startingPosition;
682  }
683 
690  bool evaluate(int &nodeNr)
691  {
692  if ( initFlag ) {
693  double distance = startingPosition->distance( this->domain->giveNode(nodeNr)->giveCoordinates() );
694 
695  if ( ( distance - distanceToClosestNode ) <= distance * 0.001 ) {
696  if ( ( distance - distanceToClosestNode ) >= -0.001 * distance ) {
697  closestNodeIndices.push_back(nodeNr);
698  } else {
699  closestNodeIndices.clear();
700  closestNodeIndices.push_back(nodeNr);
701  distanceToClosestNode = distance;
702  }
703  }
704  } else {
705  closestNodeIndices.push_back(nodeNr);
706  distanceToClosestNode = startingPosition->distance( this->domain->giveNode( * ( closestNodeIndices.begin() ) )->giveCoordinates() );
707  initFlag = true;
708  }
709 
710  return true;
711  }
712 
717  void giveResult(std :: list< int > &answer) {
718  answer = closestNodeIndices;
719  }
720 
722  {
723  return false;
724  }
725 
727  {
728  if ( initFlag ) {
729  BBXStage2.setOrigin(* startingPosition);
730  BBXStage2.setSize(distanceToClosestNode);
731  return true;
732  } else {
733  return false;
734  }
735  }
736 };
737 
738 
744 class ElementCircumCirclesContainingNode : public SL_Evaluation_Functor< DelaunayTriangle * >
745 {
746 protected:
749  std :: list< DelaunayTriangle * >result;
750 
751 public:
758  {
759  startingPosition = pos;
760  domain = d;
761  }
763 
769  bool evaluate(DelaunayTriangle * &DTptr)
770  {
771  double radius = DTptr->giveCircumRadius();
772  FloatArray centerCoords(3);
773  centerCoords.at(1) = DTptr->giveXCenterCoordinate();
774  centerCoords.at(2) = DTptr->giveYCenterCoordinate();
775  centerCoords.at(3) = 0.0;
776 
777  if ( ( startingPosition->distance(centerCoords) ) < radius ) {
778  result.push_back(DTptr);
779  return true;
780  } else {
781  return false;
782  }
783  }
784 
790  {
791  answer = * startingPosition;
792  }
793 
798  void giveResult(std :: list< DelaunayTriangle * > &answer)
799  {
800  answer = result;
801  }
802 
803  // neither stage1, nor stage 2 are defined
804  bool isBBXStage1Defined(BoundingBox &BBXStage1) { return false; }
805  bool isBBXStage2Defined(BoundingBox &BBXStage2) { return false; }
806 };
807 
813 template< class T >class OctreeSpatialLocalizerT
814 {
815 protected:
816 
818  typedef std :: list< T >dataContainerType;
819  typedef typename std :: list< T > :: iterator listIteratorType;
820  typedef typename std :: list< T > :: const_iterator listConstIteratorType;
822  CellPtrType rootCell;
823  //Domain *domain;
825 
826 public:
829  rootCell = NULL;
830  maxDepthReached = 0;
831  }
834  if ( rootCell ) {
835  delete rootCell;
836  }
837  }
838 
839  void clear () {
840  if (rootCell) delete rootCell;
841  rootCell = NULL;
842  octreeMask.zero();
843  }
845  int init(BoundingBox &BBX, int initialDivision = 0) {
846  if ( !rootCell ) {
848  BBX.giveOrigin(origin);
849  this->rootCell = new OctantRecT< T >( this, NULL, origin, BBX.giveSize() );
850  BBX.giveMask(octreeMask);
851  if ( initialDivision ) {
852  this->rootCell->divideLocally(initialDivision, this->octreeMask);
853  }
854 
855  return 1;
856  } else {
857  return 0;
858  }
859  }
860 
863  {
864  int result = 0;
865 
866  if ( functor.evaluate(memberID, rootCell) ) {
867  this->insertMemberIntoCell(memberID, functor, rootCell);
868  result = 1;
869  }
870 
871  return result;
872  }
873 
876  {
877  this->removeMemberFromCell(memberID, functor, rootCell);
878  return 1;
879  }
880 
882  void giveDataOnFilter(std :: list< T > &answer, SL_Evaluation_Functor< T > &filter)
883  {
884  typename std :: list< T > *cellDataList;
885 
886  listIteratorType pos;
887  BoundingBox BBS1, BBS2;
888  typename std :: list< CellPtrType > *cellListPostSearch = NULL;
889  typename std :: list< CellPtrType > :: iterator cellListPos;
890 
891 
892  if ( filter.isBBXStage1Defined(BBS1) ) { }
893 
894  CellPtrType terminal;
895  FloatArray startPos;
896  filter.giveStartingPosition(startPos);
897  terminal = this->findTerminalContaining(rootCell, startPos);
898 
899  cellDataList = terminal->giveDataList();
900  for ( pos = cellDataList->begin(); pos != cellDataList->end(); ++pos ) {
901  filter.evaluate(* pos);
902  }
903 
904  if ( filter.isBBXStage2Defined(BBS2) ) {
905  OctantRec :: BoundingBoxStatus BBStatus = terminal->testBoundingBox(BBS2);
906  if ( BBStatus == OctantRec :: BBS_ContainsCell ) {
907  giveListOfTerminalCellsInBoundingBox(* cellListPostSearch, BBS2, rootCell);
908  for ( cellListPos = cellListPostSearch->begin(); cellListPos != cellListPostSearch->end(); ++cellListPos ) {
909  if ( * cellListPos != terminal ) {
910  cellDataList = ( * cellListPos )->giveDataList();
911  for ( pos = cellDataList->begin(); pos != cellDataList->end(); ++pos ) {
912  filter.evaluate(* pos);
913  }
914  }
915  }
916  }
917  }
918 
919  filter.giveResult(answer);
920  }
921 
924  void proceedDataOnFilterAndRemoveFromOctree(std :: list< T > &answer, SL_Evaluation_Functor< T > &filter, SL_Insertion_Functor< T > &insertor, Timer &searchingTimer)
925  {
926  typename std :: list< T > *cellDataList;
927  listIteratorType pos, positionInDataList;
928  BoundingBox BBS1, BBS2;
929  std :: list< LocalInsertionData< T > > *insertionDataList;
930  typedef typename std :: list< LocalInsertionData< T > > :: iterator LIDiterator;
931 
932  if ( filter.isBBXStage1Defined(BBS1) ) { }
933 
934  CellPtrType terminal, cell;
935  FloatArray startingPosition;
936  filter.giveStartingPosition(startingPosition);
937  terminal = this->findTerminalContaining(rootCell, startingPosition);
938 
939  cellDataList = terminal->giveDataList();
940  for ( pos = cellDataList->begin(); pos != cellDataList->end(); ) {
941  T _obj = * pos;
942  bool ok = filter.evaluate(_obj);
943  if ( ok ) {
944  insertionDataList = insertor.giveInsertionList(_obj);
945  if ( insertionDataList ) {
946  for ( LIDiterator insDataIT = insertionDataList->begin(); insDataIT != insertionDataList->end(); insDataIT++ ) {
947  cell = ( * insDataIT ).containedInCell;
948  positionInDataList = ( * insDataIT ).posInCellDataList;
949  cell->giveDataList()->erase(positionInDataList);
950  }
951  } else {
952  // should not happen
953  removeMemberFromCell(_obj, insertor, terminal);
954  }
955 
956  // actual iterator position might not be valid, so start from beginning
957  pos = cellDataList->begin();
958  } else {
959  pos++;
960  }
961  }
962 
963  if ( filter.isBBXStage2Defined(BBS2) ) { }
964 
965  filter.giveResult(answer);
966  }
967 
968  const char *giveClassName() const { return "OctreeSpatialLocalizerT"; }
969  int giveOctreeMaskValue(int indx) { return octreeMask.at(indx); }
970  void giveOctreeMask(IntArray &answer) { answer = this->octreeMask; }
971  CellPtrType giveRootCell() { return rootCell; }
972  void giveReport()
973  {
974  // compute max. tree depth
975  int treeDepth = 0;
976  this->giveMaxTreeDepthFrom(rootCell, treeDepth);
977 
978  OOFEM_LOG_INFO("Octree structure [depth %d]\n", treeDepth);
979  }
980 
981 protected:
983  CellPtrType findTerminalContaining(CellPtrType startCell, const FloatArray &coords) {
984  int result;
985  CellPtrType currCell = startCell;
986  if ( startCell->containsPoint(coords) ) {
987  // found terminal octant containing node
988  while ( !currCell->isTerminalOctant() ) {
989  result = currCell->giveChildContainingPoint(& currCell, coords);
990  if ( result == -2 ) {
991  // report some error
992  }
993  }
994 
995  return currCell;
996  } else {
997  return NULL;
998  }
999  }
1000 
1002  int giveCellDepth(CellPtrType cell) {
1003  return ( int ) ( log( this->rootCell->giveSize() / cell->giveSize() ) / M_LN2 );
1004  }
1005 
1008  int insertMemberIntoCell(T &memberID, SL_Insertion_Functor< T > &functor, CellPtrType cell)
1009  {
1010  int i, j, k;
1011  int nCellItems, cellDepth;
1012  dataContainerType *cellDataList;
1013  listIteratorType pos;
1014  listIteratorType insertedPosition;
1016  std :: list< LocalInsertionData< T > > *insData;
1017  typedef typename std :: list< LocalInsertionData< T > > :: iterator LIDiterator;
1018 
1019  if ( cell == NULL ) {
1020  return 0;
1021  }
1022 
1023  if ( cell->isTerminalOctant() ) {
1024  cellDataList = cell->giveDataList();
1025  nCellItems = cellDataList->size();
1026  cellDepth = this->giveCellDepth(cell);
1027  if ( cellDepth > maxDepthReached ) {
1028  maxDepthReached = cellDepth;
1029 #ifdef TEMPLATED_OCTREE_DEBUG
1030  printf("Reached cell depth: %i \n", maxDepthReached);
1031 #endif
1032  }
1033 
1034  if ( ( nCellItems > TEMPLATED_OCTREE_MAX_NODES_LIMIT ) && ( cellDepth < TEMPLATED_OCTREE_MAX_DEPTH ) ) {
1035  cell->divideLocally(1, this->octreeMask);
1036 
1037 
1038 #if 1 // more memory efficient implementation
1039  while (!cellDataList->empty())
1040  {
1041  this->insertMemberIntoCell(cellDataList->back(), functor, cell);
1042  insData = functor.giveInsertionList(cellDataList->back());
1043  if ( insData ) {
1044  for ( LIDiterator insDataIT = insData->begin(); insDataIT != insData->end(); ) {
1045  if ( ( * insDataIT ).containedInCell == cell ) {
1046  insDataIT = insData->erase(insDataIT);
1047  } else {
1048  insDataIT++;
1049  }
1050  }
1051  }
1052  cellDataList->pop_back();
1053  }
1054 #else
1055  for ( pos = cellDataList->begin(); pos != cellDataList->end(); ++pos ) {
1056  this->insertMemberIntoCell(* pos, functor, cell);
1057  insData = functor.giveInsertionList(* pos);
1058  if ( insData ) {
1059  for ( LIDiterator insDataIT = insData->begin(); insDataIT != insData->end(); ) {
1060  if ( ( * insDataIT ).containedInCell == cell ) {
1061  insDataIT = insData->erase(insDataIT);
1062  } else {
1063  insDataIT++;
1064  }
1065  }
1066  }
1067  }
1068 
1069  cell->deleteDataList();
1070 #endif
1071  this->insertMemberIntoCell(memberID, functor, cell);
1072  } else { // insertion without refinement
1073  insertedPosition = cell->addMember(memberID);
1074  LIdata.containedInCell = cell;
1075  LIdata.posInCellDataList = insertedPosition;
1076 
1077  functor.registerInsertion(memberID, LIdata);
1078  return 1;
1079  }
1080  } else { // not a terminal octant, visit children
1081  CellPtrType cptr;
1082  for ( i = 0; i <= 1; i++ ) {
1083  for ( j = 0; j <= 1; j++ ) {
1084  for ( k = 0; k <= 1; k++ ) {
1085  cptr = cell->giveChild(i, j, k);
1086  if ( cptr ) {
1087  if ( functor.evaluate( memberID, cell->giveChild(i, j, k) ) ) {
1088  this->insertMemberIntoCell( memberID, functor, cell->giveChild(i, j, k) );
1089  }
1090  }
1091  }
1092  }
1093  }
1094  }
1095 
1096  return 1;
1097  }
1098 
1100  int removeMemberFromCell(T &memberID, SL_Insertion_Functor< T > &functor, CellPtrType cell)
1101  {
1102  int i, j, k;
1103  listIteratorType pos;
1104 
1105  if ( cell ) {
1106  if ( cell->isTerminalOctant() ) {
1107  if ( functor.evaluate(memberID, cell) ) {
1108  cell->removeMember(memberID);
1109  return 1;
1110  } else {
1111  return 0;
1112  }
1113  } else {
1114  for ( i = 0; i <= 1; i++ ) {
1115  for ( j = 0; j <= 1; j++ ) {
1116  for ( k = 0; k <= 1; k++ ) {
1117  this->removeMemberFromCell( memberID, functor, cell->giveChild(i, j, k) );
1118  }
1119  }
1120  }
1121  }
1122  }
1123 
1124  return 1;
1125  }
1126 
1128  void giveMaxTreeDepthFrom(CellPtrType root, int &maxDepth)
1129  {
1130  int i, j, k, depth = this->giveCellDepth(root);
1131  maxDepth = max(maxDepth, depth);
1132 
1133  for ( i = 0; i <= octreeMask.at(1); i++ ) {
1134  for ( j = 0; j <= octreeMask.at(2); j++ ) {
1135  for ( k = 0; k <= octreeMask.at(3); k++ ) {
1136  if ( root->giveChild(i, j, k) ) {
1137  this->giveMaxTreeDepthFrom(root->giveChild(i, j, k), maxDepth);
1138  }
1139  }
1140  }
1141  }
1142  }
1143 
1145  void giveListOfTerminalCellsInBoundingBox(std :: list< CellPtrType > &cellList, BoundingBox &BBX, CellPtrType currentCell)
1146  {
1147  int i, j, k;
1148  OctantRec :: BoundingBoxStatus BBStatus = currentCell->testBoundingBox(BBX);
1149  if ( ( BBStatus == OctantRec :: BBS_InsideCell ) || ( BBStatus == OctantRec :: BBS_ContainsCell ) ) {
1150  if ( currentCell->isTerminalOctant() ) {
1151  cellList.push_back(currentCell);
1152  } else {
1153  for ( i = 0; i <= octreeMask.at(1); i++ ) {
1154  for ( j = 0; j <= octreeMask.at(2); j++ ) {
1155  for ( k = 0; k <= octreeMask.at(3); k++ ) {
1156  if ( currentCell->giveChild(i, j, k) ) {
1157  this->giveListOfTerminalCellsInBoundingBox( cellList, BBX, currentCell->giveChild(i, j, k) );
1158  }
1159  }
1160  }
1161  }
1162  }
1163  }
1164  }
1165 
1166  friend class OctantRecT< T >;
1167 };
1168 } // end namespace oofem
1169 #endif // octreelocalizer_h
Templated octree cell containing data of T type.
OctantRecT< T > * CellPtrType
Squared bounding box for templated octree localizer.
void giveResult(std::list< DelaunayTriangle * > &answer)
Gives the triangles containing the node.
virtual void giveStartingPosition(FloatArray &answer)=0
Gives the starting position of the search.
void giveMaxTreeDepthFrom(CellPtrType root, int &maxDepth)
Gives the maximal tree depth from given cell.
InsertTriangleBasedOnCircumcircle(Domain *d)
Constructor.
Class and object Domain.
Definition: domain.h:115
bool evaluate(DelaunayTriangle *&DTptr)
Evaluates a triangle upon its circumscribed cricle.
void registerInsertion(DelaunayTriangle *&TEptr, LocalInsertionData< DelaunayTriangle * >LIdata)
Stores LocalInsertionData on the member.
void giveStartingPosition(FloatArray &answer)
Gives the starting position of the search.
void setMask(int i, int mask)
Sets the spatial mask.
int removeMemberFromCell(T &memberID, SL_Insertion_Functor< T > &functor, CellPtrType cell)
Removes member from cell using insertion functor to ensure member is contained in.
bool isBBXStage1Defined(BoundingBox &BBXStage1)
Stage1 means, we are looking for objects in a distance given by some boundingBox (e.g.
~BoundingBox()
Destructor.
OctantRecT< T > * containedInCell
Octant cell containing object.
~OctantRecT()
Destructor.
void zero()
Sets all component to zero.
Definition: intarray.C:52
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
int max(int i, int j)
Returns bigger value form two given decimals.
Definition: mathfem.h:71
int removeMemberFromOctree(T &memberID, SL_Insertion_Functor< T > &functor)
Removes member from octree using insertion functor - NOT IN USE.
void giveOctreeMask(IntArray &answer)
std::list< DelaunayTriangle * > result
void removeMember(T &member)
Removes member from data list.
LocalizerPtrType localizer
Octree localizer whose part of is the cell.
FloatArray origin
Origin of the cell.
bool evaluate(int &nodeNr)
Evaluates a node.
virtual bool isBBXStage1Defined(BoundingBox &BBXStage1)=0
Stage1 means, we are looking for objects in a distance given by some boundingBox (e.g.
void giveOrigin(FloatArray &answer)
Gives the cell origin.
int insertMemberIntoCell(T &memberID, SL_Insertion_Functor< T > &functor, CellPtrType cell)
Inserts member into the cell by evaluating the insertion functor Method is called recursivelly until ...
double giveCircumRadius() const
Gives the radius of the circumscribed circle.
virtual void giveResult(std::list< T > &answer)=0
Gives a container with found objects.
std::list< LocalInsertionData< DelaunayTriangle * > > * giveInsertionList(DelaunayTriangle *&DTptr)
Returns list of LocalInsertionData stored on the member.
void init(FloatArray &origin, double size, IntArray &mask)
Sets all BBOx parameters in ince.
BoundingBox()
Constructor.
virtual bool evaluate(T &obj)=0
Evaluates wether the search condition is accomplished or not.
virtual void registerInsertion(T &member, LocalInsertionData< T >LIdata)=0
Stores LocalInsertionData on the member.
virtual double giveCoordinate(int i)
Definition: node.C:82
void giveDataOnFilter(std::list< T > &answer, SL_Evaluation_Functor< T > &filter)
Evalutes the search accoring used functor a fills the list with results - NOT IN USE.
void deleteDataList()
Removes the data list.
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
Delaunay triangle for the triangulation of a set of nodes.
std::list< LocalInsertionData< DelaunayTriangle * > > * giveListOfCellsAndPosition()
Returns a list of octree cells and with iterator position in their member lists.
listIteratorType addMember(T &member)
Adds the object in to the data list returning iterator position to the object in the list...
std::list< T >::iterator listIteratorType
virtual bool isBBXStage2Defined(BoundingBox &BBXStage2)=0
Stage2BBX is given by results of a prior search.
double distance(const FloatArray &x) const
Computes the distance between position represented by receiver and position given as parameter...
Definition: floatarray.C:489
OctantRecT< T > * CellPtrType
std::list< T >::iterator listIteratorType
void giveListOfTerminalCellsInBoundingBox(std::list< CellPtrType > &cellList, BoundingBox &BBX, CellPtrType currentCell)
Gives a list of terminal cells in a bounding box.
#define TEMPLATED_OCTREE_MAX_NODES_LIMIT
Functor for finding triangles whose circumscribed circles contains given node.
std::list< int > closestNodeIndices
#define OOFEM_LOG_INFO(...)
Definition: logger.h:127
double giveYCenterCoordinate() const
Gives the y coordinate of the center of the circumscribed circle.
listIteratorType posInCellDataList
Iterator position in the list of cell objects.
int giveCellDepth(CellPtrType cell)
Returns the depth of the cell.
OctantRecT(LocalizerPtrType loc, CellPtrType parent, FloatArray &origin, double size)
Constructor.
bool isBBXStage2Defined(BoundingBox &BBXStage2)
Stage2BBX is given by results of a prior search.
#define OOFEM_ERROR(...)
Definition: error.h:61
~InsertNode()
Destructor.
CellPtrType giveChild(int xi, int yi, int zi)
Gives the Child at given local indices.
IntArray spatialMask
Spatial dimension mask.
LocalInsertionData()
Constructor.
const char * giveClassName() const
Help class for storing pointer to octant cell and position of the member in the data list...
boundingSphereStatus
void giveMask(IntArray &answer)
Gives the spatial mask of the bounding box.
double giveSize()
Gives the size of the cell.
virtual std::list< LocalInsertionData< T > > * giveInsertionList(T &member)=0
Returns list of LocalInsertionData stored on the member.
void setSize(double s)
Sets the size of the bounding box (all sides are equal)
boundingSphereStatus testBoundingSphere(const FloatArray &coords, double radius)
Tests the position of a bounding spere in relation to the octant cell.
int giveChildContainingPoint(CellPtrType *child, const FloatArray &coords)
Returns the child containing given point.
void giveStartingPosition(FloatArray &position)
Gives the starting position of the search.
std::list< T >::const_iterator listConstIteratorType
double giveXCenterCoordinate() const
Gives the x coordinate of the center of the circumscribed circle.
int divideLocally(int level, const IntArray &octantMask)
Divide receiver further, creating corresponding children.
#define M_LN2
Definition: mathfem.h:55
Class representing vector of real numbers.
Definition: floatarray.h:82
Functor for storing triangles in the octree according to theirs circumscribed circles.
double size
Size of the cell.
CellPtrType giveParent()
Functor base class responsible for insertion of members into the octree cell.
bool contains(const FloatArray &coords) const
bool evaluate(DelaunayTriangle *&DTptr, OctantRecT< DelaunayTriangle * > *cell)
Evaluates the position of a triangle.
OctantRec::BoundingBoxStatus testBoundingBox(BoundingBox &testedBBX)
Tests the position of a bounding box in relation to the octant cell.
int containsPoint(const FloatArray &coords)
Gives 1 if a given point is contained in the cell, 0 otherwise.
FloatArray origin
Starting point.
std::list< T > * giveDataList()
Return reference to member List.
virtual bool evaluate(T &member, OctantRecT< T > *cell)=0
Evaluates wether the member should be stored in the octant cell.
bool isBBXStage2Defined(BoundingBox &BBXStage2)
Stage2BBX is given by results of a prior search.
Class implementing single timer, providing wall clock and user time capabilities. ...
Definition: timer.h:46
CellPtrType findTerminalContaining(CellPtrType startCell, const FloatArray &coords)
Returns terminal octant cell containing node with coords.
int insertMemberIntoOctree(T &memberID, SL_Insertion_Functor< T > &functor)
Inserts member into the octree using functor for the evaluation.
std::list< T >::iterator listIteratorType
CellPtrType parent
Parent octree cell.
double size
Bounding box size length.
Templated octree spatial localizer.
OctreeSpatialLocalizerT< T > * LocalizerPtrType
Functor base class for evaluating search tasks on the octree according given condition.
virtual FloatArray * giveCoordinates()
Definition: node.h:114
void proceedDataOnFilterAndRemoveFromOctree(std::list< T > &answer, SL_Evaluation_Functor< T > &filter, SL_Insertion_Functor< T > &insertor, Timer &searchingTimer)
Applies the evaluation functor, fills the answer list with results and removes found object from octr...
void giveOrigin(FloatArray &answer)
Returns the bounding box origin.
int init(BoundingBox &BBX, int initialDivision=0)
Initilizes the octree structure.
bool isBBXStage1Defined(BoundingBox &BBXStage1)
Stage1 means, we are looking for objects in a distance given by some boundingBox (e.g.
bool evaluate(int &nodeNr, OctantRecT< int > *cell)
Evaluates the position of a node.
InsertNode(Domain *d)
Constuctor.
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
Node * giveNode(int n)
Service for accessing particular domain node.
Definition: domain.h:371
the oofem namespace is to define a context or scope in which all oofem names are defined.
std::list< T > * dataList
Octant cell member list.
~ClosestNode()
Destructor.
void registerInsertion(int &nodeNr, LocalInsertionData< int >LIdata)
Stores LocalInsertionData on the member.
FloatArray * startingPosition
Functor for storing nodes in the octree.
double giveSize()
Gives the size of the bounding box.
#define TEMPLATED_OCTREE_MAX_DEPTH
ClosestNode(FloatArray *pos, Domain *d)
Constructor.
std::list< LocalInsertionData< int > > * giveInsertionList(int &nodeNr)
Returns list of LocalInsertionData stored on the member.
ElementCircumCirclesContainingNode(FloatArray *pos, Domain *d)
Constructor.
void giveResult(std::list< int > &answer)
Gives the closest nodes.
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631
std::list< T >::iterator listIteratorType
void setOrigin(FloatArray &coords)
Sets the origin of the bounding box.
Functor for closest node search.

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:30 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011