meshOctreeModifierEnsureCorrectRegularity.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 "HashSet.H"
30 
31 # ifdef USE_OMP
32 #include <omp.h>
33 # endif
34 
35 //#define DEBUGSearch
36 
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
41 
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 
45 {
47 
48  //- this is needed for parallel runs to reduce the bandwidth
49  labelHashSet transferCoordinates;
50 
51  labelLongList front;
52  forAll(refineBox, leafI)
53  {
54  if( refineBox[leafI] )
55  front.append(leafI);
56  }
57 
58  DynList<label> neighbours;
59 
60  label nMarked;
61  do
62  {
63  nMarked = 0;
64  transferCoordinates.clear();
66 
67  # ifdef USE_OMP
68  # pragma omp parallel private(neighbours)
69  # endif
70  {
71  labelLongList tFront;
72 
73  # ifdef USE_OMP
74  # pragma omp for schedule(dynamic, 50)
75  # endif
76  forAll(front, i)
77  {
78  const label leafI = front[i];
79  const meshOctreeCube* oc = leaves[leafI];
80 
81  neighbours.clear();
82  octree_.findAllLeafNeighbours(*oc, neighbours);
83 
84  forAll(neighbours, neiI)
85  {
86  const label nei = neighbours[neiI];
87 
89  {
90  # ifdef USE_OMP
91  # pragma omp critical
92  # endif
93  {
94  if( !transferCoordinates.found(leafI) )
95  {
96  processorChecks.append(oc->coordinates());
97  transferCoordinates.insert(leafI);
98  }
99  }
100 
101  continue;
102  }
103 
104  if( nei < 0 )
105  continue;
106 
107  const meshOctreeCube& noc = *leaves[nei];
108 
109  if( noc.level() >= oc->level() )
110  continue;
111 
112  if( !refineBox[nei] )
113  {
114  refineBox[nei] = 1;
115  tFront.append(nei);
116  }
117  }
118  }
119 
120  # ifdef USE_OMP
121 
122  # pragma omp barrier
123 
124  # pragma omp single
125  front.clear();
126 
127  # pragma omp barrier
128 
129  # pragma omp critical
130  {
131  label start = front.size();
132  front.setSize(start+tFront.size());
133 
134  forAll(tFront, i)
135  front[start++] = tFront[i];
136  }
137  # else
138  front.transfer(tFront);
139  # endif
140  }
141 
142  nMarked = front.size();
143 
144  if( octree_.neiProcs().size() )
145  {
148  (
149  processorChecks,
150  receivedCoords
151  );
152 
153  //- check consistency with received cube coordinates
154  # ifdef USE_OMP
155  # pragma omp parallel for if( receivedCoords.size() > 100 ) \
156  schedule(dynamic, 40) private(neighbours)
157  # endif
158  forAll(receivedCoords, ccI)
159  {
160  const meshOctreeCubeCoordinates& cc = receivedCoords[ccI];
161  neighbours.clear();
162  octree_.findAllLeafNeighbours(cc, neighbours);
163 
164  forAll(neighbours, neiI)
165  {
166  const label nei = neighbours[neiI];
167 
168  if( nei < 0 )
169  continue;
170 
171  const meshOctreeCube& noc = *leaves[nei];
172 
173  if( noc.level() >= cc.level() )
174  continue;
175 
176  if( !refineBox[nei] )
177  {
178  refineBox[nei] = 1;
179 
180  # ifdef USE_OMP
181  # pragma omp critical
182  # endif
183  front.append(nei);
184  }
185  }
186  }
187 
188  nMarked = front.size();
189 
190  //- calculate the number of selected boxes over all processors
191  reduce(nMarked, sumOp<label>());
192  }
193  }
194  while( nMarked != 0 );
195 }
196 
198 {
199  const LongList<meshOctreeCube*>& leaves = octree_.leaves_;
200 
201  LongList<meshOctreeCubeCoordinates> transferCoordinates;
202 
203  label nMarked(0);
204 
205  # ifdef USE_OMP
206  # pragma omp parallel for schedule(dynamic, 100) reduction(+ : nMarked)
207  # endif
208  forAll(leaves, leafI)
209  {
210  if( !refineBox[leafI] )
211  continue;
212 
213  const meshOctreeCubeCoordinates cc = leaves[leafI]->reduceLevelBy(1);
214 
215  for(label scI=0;scI<8;++scI)
216  {
217  const label neiLeaf =
219 
220  if( neiLeaf >= 0 && !refineBox[neiLeaf] )
221  {
222  //- mark this leaf for refinement
223  ++nMarked;
224  refineBox[neiLeaf] = 1;
225  }
226  else if( neiLeaf == meshOctreeCube::OTHERPROC )
227  {
228  //- propagate this information to other processors
229  # ifdef USE_OMP
230  # pragma omp critical
231  # endif
232  transferCoordinates.append(cc);
233  }
234  }
235  }
236 
237  if( octree_.neiProcs().size() )
238  {
241  (
242  transferCoordinates,
243  receivedCoords
244  );
245 
246  # ifdef USE_OMP
247  # pragma omp parallel for if( receivedCoords.size() > 100 ) \
248  reduction(+ : nMarked)
249  # endif
250  forAll(receivedCoords, ccI)
251  {
252  const meshOctreeCubeCoordinates& cc = receivedCoords[ccI];
253 
254  for(label scI=0;scI<8;++scI)
255  {
256  const label neiLeaf =
258 
259  if( neiLeaf >= 0 && !refineBox[neiLeaf] )
260  {
261  //- mark this leaf for refinement
262  ++nMarked;
263  refineBox[neiLeaf] = 1;
264  }
265  }
266  }
267  }
268 
269  reduce(nMarked, sumOp<label>());
270 
271  if( nMarked )
272  return true;
273 
274  return false;
275 }
276 
277 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
278 
279 } // End namespace Foam
280 
281 // ************************************************************************* //
Foam::LongList::append
void append(const T &e)
Append an element at the end of the list.
Definition: LongListI.H:265
Foam::meshOctree::findAllLeafNeighbours
void findAllLeafNeighbours(const meshOctreeCubeCoordinates &, DynList< label > &neighbourLeaves) const
find neighbour leaves over nodes, edges and faces
Definition: meshOctreeNeighbourSearches.C:387
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::meshOctreeCubeCoordinates
Definition: meshOctreeCubeCoordinates.H:55
Foam::LongList::clear
void clear()
Clear the list, i.e. set next free to zero.
Definition: LongListI.H:230
Foam::meshOctree::neiProcs
const labelList & neiProcs() const
neighbour processors of the current one
Definition: meshOctreeI.H:152
Foam::LongList::size
label size() const
Size of the active part of the list.
Definition: LongListI.H:203
Foam::HashSet< label, Hash< label > >
Foam::meshOctreeCubeBasic::coordinates
const meshOctreeCubeCoordinates & coordinates() const
return coordinates in the octree
Definition: meshOctreeCubeBasicI.H:90
meshOctreeModifier.H
Foam::LongList::setSize
void setSize(const label)
Reset size of List.
Definition: LongListI.H:223
Foam::LongList
Definition: LongList.H:55
Foam::meshOctree::findLeafLabelForPosition
label findLeafLabelForPosition(const meshOctreeCubeCoordinates &) const
return leaf cube for the given position
Definition: meshOctreeNeighbourSearches.C:516
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:43
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::meshOctree::exchangeRequestsWithNeighbourProcessors
void exchangeRequestsWithNeighbourProcessors(const LongList< meshOctreeCubeCoordinates > &dataToSend, LongList< meshOctreeCubeCoordinates > &dataToReceive) const
exchange requests with other processors generating the octree
Definition: meshOctreeParallelCommunication.C:41
Foam::LongList::transfer
void transfer(LongList< T, Offset > &)
transfer the list from another one without allocating it
Definition: LongListI.H:245
Foam::meshOctreeCubeCoordinates::refineForPosition
meshOctreeCubeCoordinates refineForPosition(const label) const
return the coordinates of child cube at the given position
Definition: meshOctreeCubeCoordinatesI.H:95
HashSet.H
Foam::meshOctree::leaves_
LongList< meshOctreeCube * > leaves_
list of cubes which are leaves of the octree
Definition: meshOctree.H:89
Foam::HashTable::found
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:109
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::DynList< label >
Foam::meshOctreeCubeBasic::OTHERPROC
@ OTHERPROC
Definition: meshOctreeCubeBasic.H:93
Foam::meshOctreeModifier::ensureCorrectRegularity
void ensureCorrectRegularity(labelList &refineBox)
correct refinement such that it produces 1-irregular octree
Definition: meshOctreeModifierEnsureCorrectRegularity.C:44
Foam::sumOp
Definition: ops.H:162
Foam::meshOctreeCubeCoordinates::level
direction level() const
return level
Definition: meshOctreeCubeCoordinatesI.H:74
Foam::HashTable::clear
void clear()
Clear all entries from table.
Definition: HashTable.C:473
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::meshOctreeModifier::ensureCorrectRegularitySons
bool ensureCorrectRegularitySons(labelList &refineBox)
Definition: meshOctreeModifierEnsureCorrectRegularity.C:197
Foam::meshOctreeCube
Definition: meshOctreeCube.H:56
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:116
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::DynList::clear
void clear()
Clear the list, i.e. set next free to zero.
Definition: DynListI.H:279
Foam::meshOctreeModifier::octree_
meshOctree & octree_
Reference to the octree.
Definition: meshOctreeModifier.H:52