meshOctreeModifierParallelRefinement.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | cfMesh: A library for mesh generation
4  \\ / O peration |
5  \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6  \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
8 License
9  This file is part of cfMesh.
10 
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.
15 
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
19  for more details.
20 
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/>.
23 
24 Description
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "meshOctreeModifier.H"
29 #include "helperFunctionsPar.H"
30 #include "triSurf.H"
31 
32 #include <map>
33 
34 //#define OCTREE_DEBUG
35 
36 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40 
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 
44 (
45  const meshOctreeCubeCoordinates& cc,
46  const short procNo,
47  const direction cubeType
48 )
49 {
50  const label cpx = cc.posX();
51  const label cpy = cc.posY();
52  const label cpz = cc.posZ();
53  const direction l = cc.level();
54 
55  # ifdef OCTREE_DEBUG
56  const label levelLimiter = (1 << l);
57  if(
58  (cpx >= levelLimiter) || (cpx < 0) ||
59  (cpy >= levelLimiter) || (cpy < 0) ||
60  (cpz >= levelLimiter) || (cpz < 0)
61  )
62  {
64  (
65  "void meshOctree::refineTreeForCoordinates("
66  "const meshOctreeCubeCoordinates& cc)"
67  ) << "Trying to add an invalid cube!" << abort(FatalError);
68  }
69  # endif
70 
71  meshOctreeCube* nei(octree_.initialCubePtr_);
72 
73  for(label i=(l-1);i>=0;--i)
74  {
75  const label levelLimiter = (1 << i);
76 
77  label scI(0);
78 
79  if( cpx & levelLimiter )
80  scI |= 1;
81  if( cpy & levelLimiter )
82  scI |= 2;
83  if( cpz & levelLimiter )
84  scI |= 4;
85 
86  if( nei->isLeaf() )
87  {
88  //- refine the missing cube
90  (
91  octree_.surface_,
92  octree_.rootBox_,
93  scI
94  );
95 
96  nei = nei->subCube(scI);
97  }
98  else
99  {
100  if( !nei->subCube(scI) )
101  {
102  //- create the needed cube if it is not present
103  nei->refineMissingCube
104  (
105  octree_.surface_,
106  octree_.rootBox_,
107  scI
108  );
109  }
110 
111  nei = nei->subCube(scI);
112  }
113  }
114 
115  nei->setProcNo(procNo);
116  nei->setCubeType(cubeType);
117 }
118 
120 (
121  const meshOctreeCubeCoordinates& cc,
122  const labelList& /*containedTriangles*/,
123  const labelList& /*containedEdges*/,
124  const short procNo,
125  const direction cubeType
126 )
127 {
128  const label cpx = cc.posX();
129  const label cpy = cc.posY();
130  const label cpz = cc.posZ();
131  const direction l = cc.level();
132 
133  # ifdef OCTREE_DEBUG
134  const label levelLimiter = (1 << l);
135  if(
136  (cpx >= levelLimiter) || (cpx < 0) ||
137  (cpy >= levelLimiter) || (cpy < 0) ||
138  (cpz >= levelLimiter) || (cpz < 0)
139  )
140  {
142  (
143  "void meshOctree::refineTreeForCoordinates("
144  "const meshOctreeCubeCoordinates& cc)"
145  ) << "Trying to add an invalid cube!" << abort(FatalError);
146  }
147  # endif
148 
149  meshOctreeCube* nei(octree_.initialCubePtr_);
150 
151  for(label i=(l-1);i>=0;--i)
152  {
153  const label levelLimiter = (1 << i);
154 
155  label scI(0);
156 
157  if( cpx & levelLimiter )
158  scI |= 1;
159  if( cpy & levelLimiter )
160  scI |= 2;
161  if( cpz & levelLimiter )
162  scI |= 4;
163 
164  if( nei->isLeaf() )
165  {
166  //- refine the missing cube
167  //nei->refineMissingCube(scI, containedTrianglesI, containedEdgesI);
168  nei->refineMissingCube
169  (
170  octree_.surface_,
171  octree_.rootBox_,
172  scI
173  );
174 
175  nei = nei->subCube(scI);
176  }
177  else
178  {
179  meshOctreeCube* scPtr = nei->subCube(scI);
180 
181  if( !scPtr )
182  {
183  //- create the needed cube if it is not present
184  nei->refineMissingCube
185  (
186  octree_.surface_,
187  octree_.rootBox_,
188  scI
189  );
190  }
191 
192  nei = scPtr;
193  }
194  }
195 
196  nei->setProcNo(procNo);
197  nei->setCubeType(cubeType);
198 }
199 
201 {
202  if( !Pstream::parRun() )
203  return;
204 
205  const LongList<meshOctreeCube*>& leaves = octree_.leaves_;
206  const labelList& neiProcs = octree_.neiProcs_;
208 
209  forAll(leaves, leafI)
210  if( leaves[leafI]->procNo() != Pstream::myProcNo() )
211  return;
212 
213  Info << "Adding an additional layer of cells" << endl;
214 
215  meshOctreeCubeCoordinates minCoord, maxCoord;
216  std::map<label, LongList<meshOctreeCubeBasic> > toProcs;
217  forAll(neiProcs, i)
218  toProcs.insert
219  (
220  std::make_pair(neiProcs[i], LongList<meshOctreeCubeBasic>())
221  );
222 
223  //- fill the data into into the map
224  forAll(leaves, leafI)
225  {
226  leaves[leafI]->neighbourRange(minCoord, maxCoord);
227 
228  forAll(neiProcs, procI)
229  {
230  if(
231  (maxCoord >= neiRange[procI].first()) &&
232  (minCoord <= neiRange[procI].second())
233  )
234  toProcs[neiProcs[procI]].append(*leaves[leafI]);
235  }
236  }
237 
238  # ifdef OCTREE_DEBUG
239  for(label i=0;i<Pstream::nProcs();++i)
240  {
241  if( i == Pstream::myProcNo() )
242  {
243  std::map<label, LongList<meshOctreeCubeBasic> >::iterator it;
244  for(it=toProcs.begin();it!=toProcs.end();++it)
245  {
246  Pout << "Sending " << it->second.size() << " cubes to proc "
247  << it->first << endl;
248  }
249  }
250 
252  }
253  # endif
254 
255  //- exchange data with other processors
256  LongList<meshOctreeCubeBasic> receivedCoordinates;
257  help::exchangeMap(toProcs, receivedCoordinates, Pstream::blocking);
258 
259  # ifdef OCTREE_DEBUG
260  Pout << "Received " << receivedCoordinates.size()
261  << " from other procs" << endl;
262  # endif
263 
264  //- cubes which share a common, face, edge or vertex are added into
265  //- the current processor's tree
266  DynList<label> neighbours;
267  forAll(receivedCoordinates, ccI)
268  {
270  (
271  receivedCoordinates[ccI].coordinates(),
272  neighbours
273  );
274 
275  forAll(neighbours, neiI)
276  {
277  const label nei = neighbours[neiI];
278 
279  if( nei < 0 )
280  continue;
281 
282  if( leaves[nei]->procNo() == Pstream::myProcNo() )
283  {
285  (
286  receivedCoordinates[ccI].coordinates(),
287  receivedCoordinates[ccI].procNo(),
288  receivedCoordinates[ccI].cubeType()
289  );
290 
291  break;
292  }
293  }
294  }
295 
296  //- recalculate leaves
298 
299  # ifdef OCTREE_DEBUG
300  for(label leafI=0;leafI<octree_.numberOfLeaves();++leafI)
301  {
302  const meshOctreeCubeBasic& oc = octree_.returnLeaf(leafI);
303 
304  if( oc.procNo() == Pstream::myProcNo() )
305  continue;
306 
307  DynList<label> neighbours;
308  octree_.findAllLeafNeighbours(leafI, neighbours);
309 
310  bool found(false);
311  forAll(neighbours, i)
312  {
313  const label neiLeaf = neighbours[i];
314 
315  if( neiLeaf < 0 )
316  continue;
317  if( octree_.returnLeaf(neiLeaf).procNo() == Pstream::myProcNo() )
318  {
319  found = true;
320  break;
321  }
322  }
323 
324  if( !found )
325  FatalError << "Leaf " << leafI << " with coordinates "
326  << octree_.returnLeaf(leafI)
327  << " has no neighbour local at this processor"
328  << abort(FatalError);
329  }
330  # endif
331 
332  Info << "Finished adding an additional layer of octree cubes" << endl;
333 }
334 
335 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
336 
337 } // End namespace Foam
338 
339 // ************************************************************************* //
triSurf.H
Foam::meshOctree::findAllLeafNeighbours
void findAllLeafNeighbours(const meshOctreeCubeCoordinates &, DynList< label > &neighbourLeaves) const
find neighbour leaves over nodes, edges and faces
Definition: meshOctreeNeighbourSearches.C:387
Foam::meshOctree::neiRange_
List< Pair< meshOctreeCubeCoordinates > > neiRange_
Definition: meshOctree.H:68
Foam::meshOctreeCubeCoordinates::posX
label posX() const
return x, y, z coordinates
Definition: meshOctreeCubeCoordinatesI.H:79
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:86
helperFunctionsPar.H
Foam::meshOctreeModifier::refineTreeForCoordinates
void refineTreeForCoordinates(const meshOctreeCubeCoordinates &, const short procNo=Pstream::myProcNo(), const direction cubeType=meshOctreeCubeBasic::UNKNOWN)
refine the tree to add cubes transferred from other processors
Definition: meshOctreeModifierParallelRefinement.C:44
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::meshOctreeCubeCoordinates
Definition: meshOctreeCubeCoordinates.H:55
Foam::meshOctreeModifier::addLayerFromNeighbouringProcessors
void addLayerFromNeighbouringProcessors()
Definition: meshOctreeModifierParallelRefinement.C:200
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:387
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:377
Foam::meshOctreeCubeBasic::setCubeType
void setCubeType(const direction)
set cube type
Definition: meshOctreeCubeBasicI.H:70
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::LongList::size
label size() const
Size of the active part of the list.
Definition: LongListI.H:203
Foam::meshOctreeCube::subCube
meshOctreeCube * subCube(const label) const
return a pointer to a child cubes at given position
Definition: meshOctreeCubeI.H:71
meshOctreeModifier.H
Foam::meshOctree::numberOfLeaves
label numberOfLeaves() const
return leaves of the octree
Definition: meshOctreeI.H:48
Foam::LongList
Definition: LongList.H:55
Foam::UPstream::blocking
@ blocking
Definition: UPstream.H:66
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::Info
messageStream Info
Foam::meshOctreeCube::isLeaf
bool isLeaf() const
check if the cube is a leaf
Definition: meshOctreeCubeI.H:63
Foam::meshOctreeCube::refineMissingCube
void refineMissingCube(const triSurf &, const boundBox &, const label scI, meshOctreeSlot *slotPtr=NULL)
Definition: meshOctreeCubeRefine.C:340
coordinates
PtrList< coordinateSystem > coordinates(solidRegions.size())
Foam::meshOctreeCubeBasic::setProcNo
void setProcNo(const short)
set processor number
Definition: meshOctreeCubeBasicI.H:85
Foam::FatalError
error FatalError
Foam::meshOctree::leaves_
LongList< meshOctreeCube * > leaves_
list of cubes which are leaves of the octree
Definition: meshOctree.H:89
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::meshOctree::neiProcs_
labelList neiProcs_
Definition: meshOctree.H:63
Foam::DynList< label >
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:405
found
bool found
Definition: TABSMDCalcMethod2.H:32
Foam::sumOp
Definition: ops.H:162
Foam::meshOctreeCubeCoordinates::level
direction level() const
return level
Definition: meshOctreeCubeCoordinatesI.H:74
Foam::Pout
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::meshOctreeCube
Definition: meshOctreeCube.H:56
Foam::help::exchangeMap
void exchangeMap(const std::map< label, ListType > &m, LongList< T > &data, const Pstream::commsTypes commsType)
Definition: helperFunctionsPar.C:129
Foam::meshOctreeCubeBasic::procNo
short procNo() const
return processor number
Definition: meshOctreeCubeBasicI.H:80
Foam::direction
unsigned char direction
Definition: direction.H:43
FatalErrorIn
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:313
Foam::meshOctreeCubeCoordinates::posZ
label posZ() const
Definition: meshOctreeCubeCoordinatesI.H:89
Foam::meshOctreeCubeCoordinates::posY
label posY() const
Definition: meshOctreeCubeCoordinatesI.H:84
Foam::meshOctree::returnLeaf
const meshOctreeCubeBasic & returnLeaf(const label) const
Definition: meshOctreeI.H:60
Foam::meshOctreeCubeBasic
Definition: meshOctreeCubeBasic.H:49
Foam::meshOctreeModifier::createListOfLeaves
void createListOfLeaves()
create leaves
Definition: meshOctreeModifierI.H:100
Foam::meshOctreeModifier::octree_
meshOctree & octree_
Reference to the octree.
Definition: meshOctreeModifier.H:52