24 m_geometry = geometry;
52 return m_geometry->m_elements->size() * (5 *
sizeof(
MInt) + 2 *
sizeof(
MFloat));
59 MInt noElements = m_geometry->m_elements->size();
67 vector<MInt> from(noElements, -1);
69 vector<MInt> to(noElements, -1);
74 MInt currentDepth = 0;
83 stack<MInt> nodeStack;
89 copy_n(&m_geometry->m_minMax[0], 2 * nDim, &m_minMax[0]);
91 m_log <<
" Building tree the old way .." << endl << endl;
94 vector<MInt>::iterator it, itFrom, itTo;
95 vector<MInt> idArray(std::max(noElements, 1));
97 for(it = idArray.begin(); it != idArray.end(); it++) {
105 currentNode = m_root;
107 from.at(m_root) = idArray.front();
108 to.at(m_root) = idArray.back();
109 m_nodes[m_root].m_parent = -1;
115 m_nodes[currentNode].m_depth = currentDepth;
116 currentDir = currentDepth % (nDim * 2);
118 if(from[currentNode] != to[currentNode]) {
121 left = ++nodeCounter;
122 m_nodes[currentNode].m_leftSubtree = left;
123 m_nodes[left].m_parent = currentNode;
126 if(to[currentNode] - from[currentNode] == 1) {
128 m_nodes[currentNode].m_rightSubtree = right;
130 right = ++nodeCounter;
131 m_nodes[currentNode].m_rightSubtree = right;
132 m_nodes[right].m_parent = currentNode;
135 itFrom = idArray.begin();
136 itFrom += from[currentNode];
137 itTo = idArray.begin();
139 itTo += to[currentNode] + 1;
147 currentElement = idArray[from[currentNode]++];
148 m_nodes[currentNode].m_element = currentElement;
152 partitionId = (
MInt)((to[currentNode] - from[currentNode]) / 2 + from[currentNode]);
153 m_nodes[currentNode].m_partition = elements[idArray[partitionId]].
m_minMax[currentDir];
156 m_nodes[currentNode].m_a = elements[idArray[from[currentNode] - 1]].
m_minMax[currentDir];
157 m_nodes[currentNode].m_b = elements[idArray[to[currentNode]]].
m_minMax[currentDir];
162 from[left] = from[currentNode];
163 to[left] = partitionId;
167 from[right] = to[left] + 1;
168 to[right] = to[currentNode];
172 m_nodes[currentNode].m_leftSubtree = 0;
173 m_nodes[currentNode].m_rightSubtree = 0;
175 currentElement = idArray[to[currentNode]];
176 m_nodes[currentNode].m_element = currentElement;
177 m_nodes[currentNode].m_a = elements[from[currentNode] - 1].
m_minMax[currentDir];
178 m_nodes[currentNode].m_b = elements[to[currentNode]].
m_minMax[currentDir];
185 if(m_nodes[currentNode].m_leftSubtree) {
188 if(m_nodes[currentNode].m_rightSubtree) nodeStack.push(nodeCounter);
190 currentNode = m_nodes[currentNode].m_leftSubtree;
194 if(!nodeStack.empty()) {
195 currentNode = nodeStack.top();
197 currentDepth = m_nodes[m_nodes[currentNode].m_parent].m_depth + 1;
200 m_log <<
"ok" << endl;
215 MInt noElements = m_geometry->m_elements->size();
220 "Apparently this method can not build an adt with just one element. I observed that in 2D but did not "
232 from =
new MInt[
mMax(noElements, 0)];
239 MInt nodeCounter = 0;
240 MInt currentNode = 0;
241 MInt currentDepth = 0;
250 stack<MInt> nodeStack;
255 for(
MInt i = 0; i < 2 * nDim; i++)
256 m_minMax[i] = m_geometry->
m_minMax[i];
259 m_log <<
" + Building normal tree with " << noElements <<
" elements..." << endl;
262 vector<MInt>::iterator it, itFrom, itTo;
263 vector<MInt> idArray(noElements);
265 for(it = idArray.begin(); it != idArray.end(); it++)
269 m_log <<
" - setting root node" << endl;
274 currentNode = m_root;
276 from[m_root] = *idArray.begin();
277 to[m_root] = *(idArray.end() - 1);
278 m_nodes[m_root].m_parent = -1;
279 m_nodes[m_root].m_depth = 0;
284 if(noElements == 1) {
285 m_nodes[m_root].m_leftSubtree = left;
286 m_nodes[m_root].m_rightSubtree = right;
289 currentElement = idArray[to[m_root]];
290 m_nodes[m_root].m_element = currentElement;
291 m_nodes[m_root].m_a = elements[0].
m_minMax[currentDir];
292 m_nodes[m_root].m_b = elements[0].
m_minMax[currentDir];
294 m_log <<
" - done building the tree" << endl;
300 m_log <<
" - inserting other nodes" << endl;
301 nodeStack.push(m_root);
303 while(!nodeStack.empty()) {
304 currentNode = nodeStack.top();
306 currentDepth = m_nodes[currentNode].m_depth;
307 currentDir = currentDepth % (nDim * 2);
310 if(from[currentNode] != to[currentNode]) {
311 left = ++nodeCounter;
312 m_nodes[currentNode].m_leftSubtree = left;
313 m_nodes[left].m_parent = currentNode;
314 m_nodes[left].m_depth = currentDepth + 1;
317 if(to[currentNode] - from[currentNode] == 1) {
319 m_nodes[currentNode].m_rightSubtree = right;
321 right = ++nodeCounter;
322 m_nodes[currentNode].m_rightSubtree = right;
323 m_nodes[right].m_parent = currentNode;
324 m_nodes[right].m_depth = currentDepth + 1;
325 nodeStack.push(right);
327 nodeStack.push(left);
330 itFrom = idArray.begin();
331 itFrom += from[currentNode];
332 itTo = idArray.begin();
334 itTo += to[currentNode] + 1;
341 currentElement = idArray[from[currentNode]++];
342 m_nodes[currentNode].m_element = currentElement;
345 partitionId = (
MInt)((to[currentNode] - from[currentNode]) / 2 + from[currentNode]);
346 m_nodes[currentNode].m_partition = elements[idArray[partitionId]].
m_minMax[currentDir];
349 m_nodes[currentNode].m_a = elements[idArray[from[currentNode] - 1]].
m_minMax[currentDir];
350 m_nodes[currentNode].m_b = elements[idArray[to[currentNode]]].
m_minMax[currentDir];
355 from[left] = from[currentNode];
356 to[left] = partitionId;
360 from[right] = to[left] + 1;
361 to[right] = to[currentNode];
367 m_nodes[currentNode].m_leftSubtree = left;
368 m_nodes[currentNode].m_rightSubtree = right;
371 currentElement = idArray[to[currentNode]];
372 m_nodes[currentNode].m_element = currentElement;
373 m_nodes[currentNode].m_a = elements[from[currentNode] - 1].
m_minMax[currentDir];
374 m_nodes[currentNode].m_b = elements[to[currentNode]].
m_minMax[currentDir];
381 m_log <<
" - done building the tree" << endl;
389 m_log <<
" - Node : " << node << endl;
390 m_log <<
"parent : " << m_nodes[node].m_parent << endl;
391 m_log <<
"partition : " << m_nodes[node].m_partition << endl;
392 m_log <<
"leftSubtree : " << m_nodes[node].m_leftSubtree << endl;
393 m_log <<
"rightSubtree: " << m_nodes[node].m_rightSubtree << endl;
394 m_log <<
"depth : " << m_nodes[node].m_depth << endl;
395 m_log <<
"a : " << m_nodes[node].m_a << endl;
396 m_log <<
"b : " << m_nodes[node].m_b << endl;
416 MInt noElements = m_geometry->m_elements->size();
417 if(noElements == 0) {
422 ASSERT(nodeList.empty(),
"NodeList is not empty!");
423 MFloat t_min[2 * MAX_SPACE_DIMENSIONS];
424 MFloat t_max[2 * MAX_SPACE_DIMENSIONS];
428 for(
MInt i = 0; i < nDim; i++) {
429 t_min[i] = m_minMax[i];
430 t_min[i + nDim] = targetRegion[i];
431 t_max[i] = targetRegion[i + nDim];
432 t_max[i + nDim] = m_minMax[i + nDim];
437 stack<MInt> subtreeStack;
442 const MInt currentElementId = m_nodes[root].m_element;
443 const MFloat*
const minMax = m_geometry->m_elements->a[currentElementId].m_minMax;
444 MBool doesOverlap =
true;
446 for(
MInt i = 0; i < 2 * nDim; i++)
447 if(minMax[i] > t_max[i] || minMax[i] < t_min[i]) {
454 nodeList.push_back(currentElementId);
457 const MInt currentDir = m_nodes[root].m_depth % (2 * nDim);
460 const MInt right = m_nodes[root].m_rightSubtree;
461 if(right > 0 && m_nodes[root].m_b >= t_min[currentDir] && m_nodes[root].m_partition <= t_max[currentDir])
462 subtreeStack.push(right);
465 const MInt left = m_nodes[root].m_leftSubtree;
466 if(left > 0 && m_nodes[root].m_partition >= t_min[currentDir] && m_nodes[root].m_a <= t_max[currentDir]) {
471 if(subtreeStack.empty()) {
474 root = subtreeStack.top();
486 stringstream filename;
489 filename <<
"dxOut_all";
491 ofstream ofl(filename.str().c_str());
493 ofl <<
"object 1 class array type float rank 1 shape 3 items " << m_geometry->m_noElements * nDim <<
" data follows"
495 for(
MInt i = 0; i < m_geometry->m_noElements; i++) {
496 for(
MInt j = 0; j < nDim; j++) {
497 for(
MInt k = 0; k < nDim; k++) {
498 ofl << m_geometry->m_elements->a[i].m_vertices[j][k] <<
" ";
503 ofl <<
"object 2 class array type int rank 1 shape 3 items " << m_geometry->m_noElements <<
" data follows" << endl;
505 for(
MInt i = 0; i < m_geometry->m_noElements; i++) {
506 for(
MInt j = 0; j < nDim; j++) {
511 ofl << R
"(attribute "element type" string "triangles")" << endl;
512 ofl << R"(attribute "ref" string "positions")" << endl;
514 ofl << "object 3 class array type float rank 0 items " << m_geometry->m_noElements * 3 <<
" data follows" << endl;
516 for(
MInt i = 0; i < m_geometry->m_noElements; i++) {
517 for(
MInt j = 0; j < nDim; j++) {
523 ofl << R
"(attribute "dep" string "positions")" << endl;
525 ofl << "object \"irregular positions irregular connections\" class field" << endl;
526 ofl <<
"component \"positions\" value 1" << endl;
527 ofl <<
"component \"connections\" value 2" << endl;
528 ofl <<
"component \"data\" value 3" << endl;
793 m_log <<
"geometry m_elements size = ";
794 m_log << m_geometry->m_elements->size() << endl;
796 MInt noMBElements = m_geometry->m_mbelements->size();
806 vector<MInt> from(noMBElements, -1);
808 vector<MInt> to(noMBElements, -1);
811 MInt nodeCounter = 0;
812 MInt currentNode = 0;
813 MInt currentDepth = 0;
822 stack<MInt> nodeStack;
827 for(
MInt i = 0; i < 2 * nDim; i++) {
828 m_mbminMax[i] = m_geometry->m_mbminMax[i];
831 m_log <<
" + Building MB tree with " << noMBElements <<
" elements..." << endl << endl;
834 vector<MInt>::iterator it, itFrom, itTo;
835 vector<MInt> idArray(std::max(noMBElements, 1));
837 for(it = idArray.begin(); it != idArray.end(); it++) {
845 currentNode = m_root;
847 from.at(m_root) = idArray.front();
848 to.at(m_root) = idArray.back();
849 m_mbnodes[m_root].m_parent = -1;
850 m_mbnodes[m_root].m_depth = 0;
856 nodeStack.push(m_root);
859 while(!nodeStack.empty()) {
860 currentNode = nodeStack.top();
862 currentDepth = m_mbnodes[currentNode].m_depth;
863 currentDir = currentDepth % (nDim * 2);
866 if(from[currentNode] != to[currentNode]) {
867 left = ++nodeCounter;
868 m_mbnodes[currentNode].m_leftSubtree = left;
869 m_mbnodes[left].m_parent = currentNode;
870 m_mbnodes[left].m_depth = currentDepth + 1;
873 if(to[currentNode] - from[currentNode] == 1) {
875 m_mbnodes[currentNode].m_rightSubtree = right;
877 right = ++nodeCounter;
878 m_mbnodes[currentNode].m_rightSubtree = right;
879 m_mbnodes[right].m_parent = currentNode;
880 m_mbnodes[right].m_depth = currentDepth + 1;
881 nodeStack.push(right);
883 nodeStack.push(left);
886 itFrom = idArray.begin();
887 itFrom += from[currentNode];
888 itTo = idArray.begin();
890 itTo += to[currentNode] + 1;
897 currentElement = idArray[from[currentNode]++];
898 m_mbnodes[currentNode].m_element = currentElement;
902 partitionId = (
MInt)((to[currentNode] - from[currentNode]) / 2 + from[currentNode]);
903 m_mbnodes[currentNode].m_partition = elements[idArray[partitionId]].
m_minMax[currentDir];
906 m_mbnodes[currentNode].m_a = elements[idArray[from[currentNode] - 1]].
m_minMax[currentDir];
907 m_mbnodes[currentNode].m_b = elements[idArray[to[currentNode]]].
m_minMax[currentDir];
912 from[left] = from[currentNode];
913 to[left] = partitionId;
917 from[right] = to[left] + 1;
918 to[right] = to[currentNode];
924 m_mbnodes[currentNode].m_leftSubtree = left;
925 m_mbnodes[currentNode].m_rightSubtree = right;
927 currentElement = idArray[to[currentNode]];
928 m_mbnodes[currentNode].m_element = currentElement;
929 m_mbnodes[currentNode].m_a = elements[from[currentNode] - 1].
m_minMax[currentDir];
930 m_mbnodes[currentNode].m_b = elements[to[currentNode]].
m_minMax[currentDir];
934 m_log <<
"ok" << endl;
946 ASSERT(nodeList.empty(),
"NodeList is not empty!");
948 t_min =
new MFloat[2 * nDim];
949 t_max =
new MFloat[2 * nDim];
951 for(
MInt i = 0; i < nDim; i++) {
952 t_min[i] = m_mbminMax[i];
953 t_min[i + nDim] = targetRegion[i];
954 t_max[i] = targetRegion[i + nDim];
955 t_max[i + nDim] = m_mbminMax[i + nDim];
961 MInt currentElementId;
965 MInt searchedNodes = 0;
966 stack<MInt> subtreeStack;
968 currentDir = m_mbnodes[root].m_depth % (2 * nDim);
969 currentElementId = m_mbnodes[root].m_element;
970 currentElement = &mbelements[currentElementId];
976 for(
MInt i = 0; i < 2 * nDim; i++) {
977 if(currentElement->
m_minMax[i] <= t_max[i] && currentElement->
m_minMax[i] >= t_min[i]) {
986 nodeList.push_back(currentElementId);
990 right = m_mbnodes[root].m_rightSubtree;
992 if(m_mbnodes[root].m_b >= t_min[currentDir] && m_mbnodes[root].m_partition <= t_max[currentDir])
993 subtreeStack.push(right);
996 left = m_mbnodes[root].m_leftSubtree;
998 if(m_mbnodes[root].m_partition >= t_min[currentDir] && m_mbnodes[root].m_a <= t_max[currentDir]) {
1003 if(subtreeStack.empty()) {
1010 root = subtreeStack.top();
void retrieveNodes(MFloat *targetRegion, std::vector< MInt > &nodeList) const
retrieves the nodes that intersect with a given target bounding box
void retrieveNodesMBElements(const MFloat *targetRegion, std::vector< MInt > &nodeList) const
GeometryAdt(const Geometry< nDim > *geometry)
void buildTree()
Create an ADT from the geometry.
void splitTree(MInt noSubTrees)
void writeNode(MInt node)
void mTerm(const MInt errorCode, const MString &location, const MString &message)
constexpr T mMax(const T &x, const T &y)