59 for (
int i = 0; i <= 1; i++ ) {
60 for (
int j = 0; j <= 1; j++ ) {
61 for (
int k = 0; k <= 1; k++ ) {
62 this->
child [ i ] [ j ] [ k ] = NULL;
72 for (
int i = 0; i <= 1; i++ ) {
73 for (
int j = 0; j <= 1; j++ ) {
74 for (
int k = 0; k <= 1; k++ ) {
75 if ( this->
child [ i ] [ j ] [ k ] ) {
76 delete this->
child [ i ] [ j ] [ k ];
108 if ( ( xi >= 0 ) && ( xi < 2 ) && ( yi >= 0 ) && ( yi < 2 ) && ( zi >= 0 ) && ( zi < 2 ) ) {
109 return this->
child [ xi ] [ yi ] [ zi ];
111 OOFEM_ERROR(
"invalid child index (%d,%d,%d)", xi, yi, zi);
128 for (
int i = 1; i <= coords.
giveSize(); ++i ) {
132 * child = this->child [ ind.
at(1) ] [ ind.
at(2) ] [ ind.
at(3) ];
142 if ( this->
child [ 0 ] [ 0 ] [ 0 ] ) {
157 for (
int i = 0; i <= octantMask.
at(1); i++ ) {
158 for (
int j = 0; j <= octantMask.
at(2); j++ ) {
159 for (
int k = 0; k <= octantMask.
at(3); k++ ) {
169 int newLevel = level - 1;
170 if ( newLevel > 0 ) {
172 for (
int i = 0; i <= octantMask.
at(1); i++ ) {
173 for (
int j = 0; j <= octantMask.
at(2); j++ ) {
174 for (
int k = 0; k <= octantMask.
at(3); k++ ) {
175 if ( this->
child [ i ] [ j ] [ k ] ) {
191 bool bbInside =
true;
193 for (
int i = 1; i <= size; i++ ) {
195 bb0 = coords.
at(i) - radius;
196 bb1 = coords.
at(i) + radius;
200 if ( oct1 < bb0 || oct0 > bb1 ) {
204 bbInside = bbInside && oct0 < bb0 && oct1 > bb1;
217 if ( this->
depth == 0 ) {
218 printf(
"*ROOTCELL*");
221 for (
int i = 0; i <= 1; i++ ) {
222 for (
int j = 0; j <= 1; j++ ) {
223 for (
int k = 0; k <= 1; k++ ) {
224 if ( this->
child [ i ] [ j ] [ k ] ) {
225 for (
int q = 0; q < this->
depth - 1; q++ ) {
263 OOFEM_ERROR(
"internal error - octree inconsistency");
275 double rootSize, resolutionLimit;
294 for (
int i = 1; i <= nnode; i++ ) {
296 node =
dynamic_cast< Node *
>(dman);
301 for (
int j = 1; j <= coords->
giveSize(); j++ ) {
302 minc.
at(j) = maxc.at(j) = coords->
at(j);
305 for (
int j = 1; j <= coords->
giveSize(); j++ ) {
306 if ( coords->
at(j) < minc.at(j) ) {
307 minc.at(j) = coords->
at(j);
310 if ( coords->
at(j) > maxc.at(j) ) {
311 maxc.at(j) = coords->
at(j);
320 for (
int i = 1; i <= 3; i++ ) {
321 rootSize = 1.000001 *
max( rootSize, maxc.at(i) - minc.at(i) );
325 resolutionLimit =
min(1.e-3, rootSize / 1.e6);
326 for (
int i = 1; i <= 3; i++ ) {
327 if ( ( maxc.at(i) - minc.at(i) ) > resolutionLimit ) {
346 for (
int i = 1; i <= nnode; i++ ) {
348 node =
dynamic_cast< Node *
>(dman);
379 for (
int i = 1; i <= nelems; i++ ) {
461 for (
int i = 1; i <= b0.
giveSize(); i++ ) {
463 bbc [ 0 ].
at(i) = b0.
at(i) <= origin.
at(i);
464 bbc [ 1 ].
at(i) = b1.
at(i) >= origin.
at(i);
466 bbc [ 0 ].
at(i) = bbc [ 1 ].
at(i) =
true;
469 for (
int i = b0.
giveSize() + 1; i <= 3; i++ ) {
470 bbc [ 0 ].
at(i) = bbc [ 1 ].
at(i) =
true;
479 if ( bbc [ i ].at(1) ) {
481 if ( bbc [ j ].at(2) ) {
483 if ( bbc [ k ].at(3) && rootCell->
giveChild(i, j, k) ) {
502 if ( dofmanConnectivity ) {
503 for (
int d: *dofmanConnectivity ) {
525 int nCellItems, cellDepth;
533 nCellItems = cellNodeList.size();
542 for (
int inod: cellNodeList ) {
563 OOFEM_ERROR(
"internal error - octree inconsistency");
583 while ( currCell != NULL ) {
590 childCell = currCell;
611 while ( currCell != NULL ) {
618 childCell = currCell;
638 for (
int iel: elementList ) {
652 if ( interface->SpatialLocalizerI_BBoxContainsPoint(coords) == 0 ) {
656 if ( interface->SpatialLocalizerI_containsPoint(coords) ) {
670 if ( scannedChild == cell->
giveChild(i, j, k) ) {
696 for (
int iel: elementList ) {
710 if ( interface->SpatialLocalizerI_BBoxContainsPoint(coords) == 0 ) {
714 if ( interface->SpatialLocalizerI_containsPoint(coords) ) {
727 if ( scannedChild == cell->
giveChild(i, j, k) ) {
750 std :: list< OctantRec * >cellList;
752 double radius, prevRadius;
768 while ( radius < minDist ) {
789 if ( !elementList.empty() ) {
790 for (
int iel: elementList ) {
802 if ( currDist < minDist ) {
803 lcoords = currLcoords;
804 closest = currClosest;
809 if ( minDist == 0.0 ) {
836 for (
int iel: elementList ) {
849 if ( !iCohesiveZoneGP ) {
855 double dist = coords.
distance(jGpCoords);
856 if ( dist < minDist ) {
869 if ( xFemEl != NULL ) {
871 for (
size_t czRuleIndex = 0; czRuleIndex < numCZRules; czRuleIndex++ ) {
877 double dist = coords.
distance(jGpCoords);
879 if ( dist < minDist ) {
903 std :: list< OctantRec * >cellList;
920 if ( currCell == icell ) {
950 set< int >nearElementList;
955 if ( !nearElementList.empty() ) {
956 for (
int elnum: nearElementList ) {
959 if ( region == ielem->giveRegionNumber() ) {
962 if ( ielem->computeGlobalCoordinates( jGpCoords, * ( jGp->giveCoordinates() ) ) ) {
964 double dist = coords.
distance(jGpCoords);
965 if ( dist < minDist ) {
990 int region,
double &dist,
GaussPoint **answer,
bool iCohesiveZoneGP)
998 for (
int iel: elementList ) {
1011 if ( !iCohesiveZoneGP ) {
1017 currDist = coords.
distance(jGpCoords);
1019 if ( currDist <= dist ) {
1032 if ( xFemEl != NULL ) {
1034 for (
size_t czRuleIndex = 0; czRuleIndex < numCZRules; czRuleIndex++ ) {
1039 currDist = coords.
distance(jGpCoords);
1041 if ( currDist <= dist ) {
1063 if ( currentCell->
giveChild(i, j, k) ) {
1098 for (
int iel: elementList) {
1111 if ( !iCohesiveZoneGP ) {
1117 double dist = coords.
distance(jGpCoords);
1118 if ( dist < minDist ) {
1131 if ( xFemEl != NULL ) {
1133 for (
size_t czRuleIndex = 0; czRuleIndex < numCZRules; czRuleIndex++ ) {
1139 double dist = coords.
distance(jGpCoords);
1141 if ( dist < minDist ) {
1165 std :: list< OctantRec * >cellList;
1182 if ( currCell == icell ) {
1212 set< int >nearElementList;
1217 if ( !nearElementList.empty() ) {
1218 for (
int iel: nearElementList ) {
1225 double dist = coords.
distance(jGpCoords);
1226 if ( dist < minDist ) {
1251 Set &elementSet,
double &dist,
GaussPoint **answer,
bool iCohesiveZoneGP)
1259 for (
int iel: elementList ) {
1272 if ( !iCohesiveZoneGP ) {
1278 currDist = coords.
distance(jGpCoords);
1280 if ( currDist <= dist ) {
1293 if ( xFemEl != NULL ) {
1295 for (
size_t czRuleIndex = 0; czRuleIndex < numCZRules; czRuleIndex++ ) {
1300 currDist = coords.
distance(jGpCoords);
1302 if ( currDist <= dist ) {
1324 if ( currentCell->
giveChild(i, j, k) ) {
1342 const double radius,
bool iCohesiveZoneGP)
1365 const double radius,
bool iCohesiveZoneGP)
1376 const FloatArray &coords,
const double radius,
bool iCohesiveZoneGP)
1384 for (
int iel: elementList ) {
1394 if ( !iCohesiveZoneGP ) {
1398 currDist = coords.
distance(jGpCoords);
1400 if ( currDist <= radius ) {
1413 if ( xFemEl != NULL ) {
1415 for (
size_t czRuleIndex = 0; czRuleIndex < numCZRules; czRuleIndex++ ) {
1418 for (
auto &gp: *iRule ) {
1420 currDist = coords.
distance(jGpCoords);
1422 if ( currDist <= radius ) {
1424 czRuleIndex = numCZRules;
1444 if ( currentCell->
giveChild(i, j, k) ) {
1483 Node *answer = NULL;
1484 std :: list< OctantRec * >cellList;
1486 double radius, prevRadius;
1489 double minDist = maxDist;
1503 prevRadius = radius;
1505 }
while ( prevRadius < minDist );
1512 double &minDist,
Node * &answer)
1514 double minDist2 = minDist*minDist;
1520 if ( currDist2 < minDist2 ) {
1522 minDist2 = currDist2;
1525 minDist = sqrt(minDist2);
1531 const FloatArray &coords,
const double radius)
1537 if ( !cellNodes.empty() ) {
1538 for (
int inod: cellNodes ) {
1542 if ( nodeCoords->
distance(coords) <= radius ) {
1554 if ( currentCell->
giveChild(i, j, k) ) {
1573 maxDepth =
max(maxDepth, depth);
1589 double radius,
double innerRadius,
OctantRec *currentCell)
1597 cellList.push_back(currentCell);
1603 if ( currentCell->
giveChild(i, j, k) ) {
virtual Element * giveElementClosestToPoint(FloatArray &lcoords, FloatArray &closest, const FloatArray &gcoords, int region)
Returns the element closest to a given point.
void giveClosestIPWithinOctant(OctantRec *currentCell, const FloatArray &coords, int region, double &dist, GaussPoint **answer, bool iCohesiveZoneGP)
Returns closest IP to given point contained within given octree cell.
The base class for all spatial localizers.
virtual ~OctreeSpatialLocalizer()
Destructor - deletes the octree tree.
void giveNodeClosestToPointWithinOctant(OctantRec *cell, const FloatArray &gcoords, double &minDist, Node *&answer)
Returns the node closest to the given point within the cell.
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
Access method for default integration rule.
void insertElementIntoOctree(OctantRec *rootCell, int region, int elemNum, const FloatArray &b0, const FloatArray &b1)
Inserts an element with the given bounding box.
The implementation of spatial localizer based on octree technique.
void insertNodeIntoOctree(OctantRec *rootCell, int nodeNum, const FloatArray &coords)
Inserts the given node (identified by its number and position) to the octree structure.
int giveNumberOfDofManagers() const
Returns number of dof managers in domain.
IntArray elementListsInitialized
Provides Xfem interface for an element.
std::list< int > nodeList
Octant node list.
bool isEmpty() const
Checks if receiver is empty (i.e., zero sized).
OctreeSpatialLocalizer * localizer
Link to octree class.
void zero()
Sets all component to zero.
double & at(int i)
Coefficient access function.
int max(int i, int j)
Returns bigger value form two given decimals.
OctreeSpatialLocalizer(Domain *d)
Constructor.
std::list< int > & giveNodeList()
ConnectivityTable * giveConnectivityTable()
Returns receiver's associated connectivity table.
bool insertSortedOnce(int value, int allocChunk=0)
Inserts given value into a receiver, which is assumed to be sorted.
FloatArray origin
Octant origin coordinates (lower corner)
int giveOctreeMaskValue(int indx)
Returns the octreeMask value given by the index.
Abstract base class for all finite elements.
void deleteNodeList()
Clears and deletes the nodeList.
Base class for dof managers.
int giveNumberOfElements() const
Returns number of elements in domain.
Class representing the octant of octree.
std::list< int > & giveElementList(int region)
#define OOFEM_LOG_DEBUG(...)
Class implementing an array of integers.
int & at(int i)
Coefficient access function.
Domain * domain
Link to domain object.
int giveNumberOfIntegrationRules()
#define OCTREE_MAX_NODES_LIMIT
Max desired number of nodes per octant.
virtual int giveNumberOfNodes() const
Returns number of nodes of receiver.
std::list< int > nodeContainerType
Typedefs to introduce the container type for nodal numbers, returned by some services.
double distance(const FloatArray &x) const
Computes the distance between position represented by receiver and position given as parameter...
virtual double SpatialLocalizerI_giveClosestPoint(FloatArray &lcoords, FloatArray &closest, const FloatArray &gcoords)
Gives the closest point on the element.
void printYourself()
Recursively prints structure.
BoundingBoxStatus testBoundingBox(const FloatArray &coords, double radius)
Test if receiver within bounding box (sphere).
Element * giveElement(int n)
Service for accessing particular domain fe element.
#define OCTREE_MAX_DEPTH
Max octree depth.
IntArray & giveIPElementList()
ChildStatus giveChildContainingPoint(OctantRec **child, const FloatArray &coords)
Returns the child containing given point.
void clear()
Clears the array (zero size).
Set of elements, boundaries, edges and/or nodes.
void insertIPElementIntoOctree(OctantRec *rootCell, int elemNum, const FloatArray &coords)
Inserts the given integration point (or more precisely the element owning it) to the octree data stru...
void giveListOfTerminalCellsInBoundingBox(std::list< OctantRec * > &cellList, const FloatArray &coords, const double radius, double innerRadius, OctantRec *currentCell)
Builds the list of terminal cells contained within given box (coords, radius), starting from given cu...
bool elementIPListsInitialized
Flag indicating elementIP tables are initialized.
OctantRec * rootCell
Root cell of octree.
IntArray octreeMask
Octree degenerate mask.
virtual void SpatialLocalizerI_giveBBox(FloatArray &bb0, FloatArray &bb1)
Creates a bounding box of the nodes and checks if it includes the given coordinate.
double distance_square(const FloatArray &iP1, const FloatArray &iP2, double &oXi, double &oXiUnbounded) const
void resize(int n)
Checks size of receiver towards requested bounds.
virtual Node * giveNodeClosestToPoint(const FloatArray &coords, double maxDist)
Returns the node closest to the given coordinate.
std::vector< std::unique_ptr< IntegrationRule > > mpCZIntegrationRules
virtual void giveAllElementsWithIpWithinBox_EvenIfEmpty(elementContainerType &elemSet, const FloatArray &coords, const double radius)
Returns container (set) of all domain elements having integration point within given box...
virtual int init(bool force=false)
Initialize receiver data structure if not done previously.
virtual Element * giveElementContainingPoint(const FloatArray &coords, const IntArray *regionList=NULL)
Returns the element, containing given point and belonging to one of the region in region list...
void addElement(int region, int elementNum)
Adds given element to cell list of elements having IP within this cell.
Class representing vector of real numbers.
elementParallelMode giveParallelMode() const
Return elementParallelMode of receiver.
int findSorted(int value) const
Finds the first occurrence of given value, assuming that the receiver is sorted.
void addNode(int nodeNum)
Adds given Node to node list of nodes contained by receiver.
const IntArray * giveDofManConnectivityArray(int dofman)
bool buildOctreeDataStructure()
Builds the underlying octree data structure.
virtual GaussPoint * giveClosestIP(const FloatArray &coords, int region, bool iCohesiveZoneGP=false)
Returns the integration point in associated domain, which is closest to given point.
virtual void printYourself() const
Print receiver on stdout.
OctantRec(OctreeSpatialLocalizer *loc, OctantRec *parent, FloatArray &origin, double halfWidth)
Constructor.
OctantRec * giveChild(int xi, int yi, int zi)
Gives the Child at given local indices.
virtual void giveAllNodesWithinBox(nodeContainerType &nodeList, const FloatArray &coords, const double radius)
Returns container (list) of all domain nodes within given box.
virtual void giveAllElementsWithIpWithinBox(elementContainerType &elemSet, const FloatArray &coords, const double radius)
Returns container (set) of all domain elements having integration point within given box...
Class implementing single timer, providing wall clock and user time capabilities. ...
double halfWidth
Octant size.
std::vector< std::list< int > > elementList
Element list of all elements close to the cell.
virtual Interface * giveInterface(InterfaceType t)
Interface requesting service.
void times(double s)
Multiplies receiver with scalar.
int giveNumberOfRegions() const
Returns number of regions. Currently regions corresponds to cross section models. ...
The spatial localizer element interface associated to spatial localizer.
Element in active domain is only mirror of some remote element.
virtual FloatArray * giveCoordinates()
void insertElementsUsingNodalConnectivitiesIntoOctree(OctantRec *rootCell)
Initializes the element lists in octree data structure.
IntArray elementIPList
Element list, containing all elements having IP in cell.
int min(int i, int j)
Returns smaller value from two given decimals.
void giveMaxTreeDepthFrom(OctantRec *root, int &maxDepth)
Determines the max tree depth computed for given tree cell and its children.
void push_back(const double &iVal)
Add one element.
const FloatArray & giveOrigin()
Gives the cell origin.
void divideLocally(int level, const IntArray &octantMask)
Divide receiver further, creating corresponding children.
void giveElementsWithIPWithinBox(elementContainerType &elemSet, OctantRec *currentCell, const FloatArray &coords, const double radius, bool iCohesiveZoneGP=false)
Returns container (set) of elements having integration point within given box and given root cell...
void initElementDataStructure(int region=0)
Insert element into tree (the tree topology is determined by nodes).
OctantRec * child[2][2][2]
Link to octant children.
int giveSize() const
Returns the size of receiver.
Node * giveNode(int n)
Service for accessing particular domain node.
the oofem namespace is to define a context or scope in which all oofem names are defined.
Class implementing node in finite element mesh.
Domain * giveDomain()
Returns the domain that localizer acts on.
DofManager * giveDofManager(int n)
Service for accessing particular domain dof manager.
void addElementIP(int elementNum)
Adds given element to cell list of elements having IP within this cell.
void giveNodesWithinBox(nodeContainerType &nodeList, OctantRec *currentCell, const FloatArray &coords, const double radius)
Returns container (list) of nodes within given box and given root cell.
Node * giveNode(int i) const
Returns reference to the i-th node of element.
double getUtime()
Returns total user time elapsed in seconds.
void giveElementClosestToPointWithinOctant(OctantRec *currCell, const FloatArray &gcoords, double &minDist, FloatArray &lcoords, FloatArray &closest, Element *&answer, int region)
Returns the element closest to the given point within the cell.
Class representing integration point in finite element program.
bool hasElement(int elem) const
Return True if given element is contained.
OctantRec * findTerminalContaining(OctantRec *startCell, const FloatArray &coords)
Finds the terminal octant containing the given point.
virtual int computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords)
Computes the global coordinates from given element's local coordinates.
void add(const FloatArray &src)
Adds array src to receiver.
void initElementIPDataStructure()
Insert IP records into tree (the tree topology is determined by nodes).
int findFirstIndexOf(int value) const
Finds index of first occurrence of given value in array.