1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | cfMesh: A library for mesh generation
5 \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6 \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of cfMesh.
11 cfMesh is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 3 of the License, or (at your
14 option) any later version.
16 cfMesh is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with cfMesh. If not, see <http://www.gnu.org/licenses/>.
26 \*---------------------------------------------------------------------------*/
28 #include "meshOctree.H"
31 //#define OCTREE_DEBUG
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 // Private member functions
41 label meshOctree::findLeafContainingVertex
47 Info << "Finding leaf for vertex " << p << endl;
50 const meshOctreeCube* ocPtr = initialCubePtr_;
52 if( !ocPtr->isVertexInside(rootBox_, p) )
55 Info << "Vertex " << p << " is not in the initial cube" << endl;
64 if( ocPtr && !ocPtr->isLeaf() )
66 //- find a subCube containing the vertex;
67 const point c = ocPtr->centre(rootBox_);
75 if( !isQuadtree_ && p.z() >= c.z() )
78 ocPtr = ocPtr->subCube(scI);
88 return ocPtr->cubeLabel();
91 return meshOctreeCubeBasic::OTHERPROC;
94 label meshOctree::findNeighbourOverNode
96 const meshOctreeCubeCoordinates& cc,
103 const meshOctreeCubeCoordinates nc(cc + regularityPositions_[18+nodeI]);
105 const meshOctreeCube* neiPtr = findCubeForPosition(nc);
109 const label levelLimiter = (1 << cc.level());
111 (nc.posX() >= levelLimiter) || (nc.posX() < 0) ||
112 (nc.posY() >= levelLimiter) || (nc.posY() < 0) ||
113 (!isQuadtree_ && (nc.posZ() >= levelLimiter || nc.posZ() < 0)) ||
114 (isQuadtree_ && (nc.posZ() != initialCubePtr_->posZ()))
119 else if( Pstream::parRun() )
121 return meshOctreeCubeBasic::OTHERPROC;
126 else if( neiPtr->isLeaf() )
129 if( leaves_[neiPtr->cubeLabel()] != neiPtr )
130 FatalError << "Cube does not correspond to itself"
131 << abort(FatalError);
133 return neiPtr->cubeLabel();
137 FixedList<label, 8> sc(-1);
138 for(label scI=0;scI<8;++scI)
140 meshOctreeCube* scPtr = neiPtr->subCube(scI);
143 sc[scI] = scPtr->cubeLabel();
145 else if( Pstream::parRun() )
147 sc[scI] = meshOctreeCubeBasic::OTHERPROC;
156 "label meshOctree::findNeighbourOverNode("
157 "const meshOctreeCubeCoordinates& cc,"
158 "const label nodeI) const"
159 ) << "Should not be here!" << abort(FatalError);
164 void meshOctree::findNeighboursOverEdge
166 const meshOctreeCubeCoordinates& cc,
168 DynList<label>& neighbourLeaves
171 if( isQuadtree_ && (eI >= 8) )
173 neighbourLeaves.append(-1);
177 const meshOctreeCubeCoordinates nc(cc + regularityPositions_[6+eI]);
179 const meshOctreeCube* neiPtr = findCubeForPosition(nc);
183 const label levelLimiter = (1 << cc.level());
185 (nc.posX() >= levelLimiter) || (nc.posX() < 0) ||
186 (nc.posY() >= levelLimiter) || (nc.posY() < 0) ||
187 (!isQuadtree_ && (nc.posZ() >= levelLimiter || nc.posZ() < 0)) ||
188 (isQuadtree_ && (nc.posZ() != initialCubePtr_->posZ()))
191 neighbourLeaves.append(-1);
193 else if( Pstream::parRun() )
195 neighbourLeaves.append(meshOctreeCubeBasic::OTHERPROC);
198 else if( neiPtr->isLeaf() )
201 if( leaves_[neiPtr->cubeLabel()] != neiPtr )
202 FatalError << "Cube does not correspond to itself"
203 << abort(FatalError);
205 neighbourLeaves.append(neiPtr->cubeLabel());
209 FixedList<label, 8> sc(-1);
210 for(label scI=0;scI<8;++scI)
212 meshOctreeCube* scPtr = neiPtr->subCube(scI);
216 sc[scI] = scPtr->cubeLabel();
218 else if( Pstream::parRun() )
220 sc[scI] = meshOctreeCubeBasic::OTHERPROC;
224 const label* eNodes = meshOctreeCubeCoordinates::edgeNodes_[eI];
228 neighbourLeaves.append(sc[7-eNodes[1]]);
229 neighbourLeaves.append(sc[7-eNodes[0]]);
233 if( sc[7-eNodes[1]] >= 0 )
234 neighbourLeaves.append(sc[7-eNodes[1]]);
235 if( (sc[7-eNodes[0]] >= 0) && (sc[7-eNodes[0]] != sc[7-eNodes[1]]) )
236 neighbourLeaves.append(sc[7-eNodes[0]]);
241 void meshOctree::findNeighboursInDirection
243 const meshOctreeCubeCoordinates& cc,
245 DynList<label>& neighbourLeaves
248 if( isQuadtree_ && dir >= 4 )
250 neighbourLeaves.append(-1);
254 label cpx = cc.posX();
255 label cpy = cc.posY();
256 label cpz = cc.posZ();
291 const meshOctreeCube* neiPtr =
294 meshOctreeCubeCoordinates(cpx, cpy, cpz, cc.level())
299 const label levelLimiter = (1 << cc.level());
301 (cpx >= levelLimiter) || (cpx < 0) ||
302 (cpy >= levelLimiter) || (cpy < 0) ||
303 (!isQuadtree_ && (cpz >= levelLimiter || cpz < 0)) ||
304 (isQuadtree_ && (cpz != initialCubePtr_->posZ()))
307 neighbourLeaves.append(-1);
309 else if( Pstream::parRun() )
311 neighbourLeaves.append(meshOctreeCubeBasic::OTHERPROC);
314 else if( neiPtr->isLeaf() )
317 if( leaves_[neiPtr->cubeLabel()] != neiPtr )
318 FatalError << "Cube does not correspond to itself"
319 << abort(FatalError);
321 neighbourLeaves.append(neiPtr->cubeLabel());
325 FixedList<label, 8> sc(-1);
326 for(label scI=0;scI<8;++scI)
328 meshOctreeCube* scPtr = neiPtr->subCube(scI);
332 sc[scI] = scPtr->cubeLabel();
334 else if( Pstream::parRun() )
336 sc[scI] = meshOctreeCubeBasic::OTHERPROC;
340 const label* fNodes = meshOctreeCubeCoordinates::faceNodes_[dir];
341 for(label i=0;i<4;++i)
343 if( isQuadtree_ && sc[7-fNodes[i]] < 0 )
346 neighbourLeaves.append(sc[7-fNodes[i]]);
351 void meshOctree::findNeighboursForLeaf
353 const meshOctreeCubeCoordinates& cc,
354 DynList<label>& neighbourLeaves
357 neighbourLeaves.clear();
359 const label nCubeFaces = isQuadtree_?4:6;
360 for(label i=0;i<nCubeFaces;++i)
362 findNeighboursInDirection(cc, i, neighbourLeaves);
366 void meshOctree::findAllLeafNeighbours
368 const meshOctreeCubeCoordinates& cc,
369 DynList<label>& neighbourLeaves
372 neighbourLeaves.clear();
374 //- neighbours over nodes
377 for(label i=0;i<8;++i)
378 neighbourLeaves.append(findNeighbourOverNode(cc, i));
381 //- neighbours over edges
382 const label nCubeEdges = isQuadtree_?8:12;
383 for(label i=0;i<nCubeEdges;++i)
384 findNeighboursOverEdge(cc, i, neighbourLeaves);
386 //- neighbours over faces
387 const label nCubeFaces = isQuadtree_?4:6;
388 for(label i=0;i<nCubeFaces;++i)
389 findNeighboursInDirection(cc, i, neighbourLeaves);
392 void meshOctree::findLeavesForCubeVertex
395 const direction vrtI,
396 FixedList<label, 8>& neighbours
399 const meshOctreeCube* oc = leaves_[leafI];
400 const meshOctreeCubeCoordinates cc = oc->refineForPosition(vrtI);
402 FixedList<meshOctreeCubeCoordinates, 8> positions;
404 for(label i=0;i<8;++i)
406 positions[i] = cc + vrtLeavesPos_[vrtI][i];
409 forAll(positions, posI)
411 neighbours[posI] = -1;
413 const label nei = findLeafLabelForPosition(positions[posI]);
415 if( (nei > -1) && leaves_[nei]->isLeaf() )
416 neighbours[posI] = nei;
420 Info << "Cube " << *oc << endl;
421 Info << "Vertex " << short(vrtI) << endl;
422 Info << "Neighbours " << endl;
423 forAll(neighbours, nI)
425 Info << *neighbours[nI] << endl;
429 meshOctreeCube* meshOctree::findCubeForPosition
431 const meshOctreeCubeCoordinates& cc
435 Info << "Finding position " << cc << endl;
438 const label cpx = cc.posX();
439 const label cpy = cc.posY();
440 const label cpz = cc.posZ();
441 const direction l = cc.level();
443 label levelLimiter = (1 << l);
445 (cpx >= levelLimiter) || (cpx < 0) ||
446 (cpy >= levelLimiter) || (cpy < 0) ||
447 (!isQuadtree_ && (cpz >= levelLimiter || cpz < 0)) ||
448 (isQuadtree_ && (cpz != initialCubePtr_->posZ()))
454 meshOctreeCube* neiPtr(initialCubePtr_);
456 for(label i=(l-1);i>=0;--i)
458 if( neiPtr && !neiPtr->isLeaf() )
460 levelLimiter = (1 << i);
464 if( cpx & levelLimiter )
466 if( cpy & levelLimiter )
468 if( !isQuadtree_ && (cpz & levelLimiter) )
471 neiPtr = neiPtr->subCube(scI);
480 Info << "Found position is " << *neiPtr << endl;
486 label meshOctree::findLeafLabelForPosition
488 const meshOctreeCubeCoordinates& cc
491 const meshOctreeCube* ocPtr = findCubeForPosition(cc);
493 if( ocPtr && ocPtr->isLeaf() )
495 return ocPtr->cubeLabel();
497 else if( !ocPtr && (neiProcs_.size() != 0) )
499 const label levelLimiter = (1 << cc.level());
501 (cc.posX() < levelLimiter) && (cc.posX() >= 0) &&
502 (cc.posY() < levelLimiter) && (cc.posY() >= 0) &&
503 ((!isQuadtree_ && (cc.posZ() < levelLimiter && cc.posZ() >= 0)) ||
504 (isQuadtree_ && (cc.posZ() == initialCubePtr_->posZ())))
507 return meshOctreeCubeBasic::OTHERPROC;
514 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
516 } // End namespace Foam
518 // ************************************************************************* //