boundaryLayersCheckTopologyOfBndFaces.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 "boundaryLayers.H"
29 #include "meshSurfaceEngine.H"
30 #include "decomposeCells.H"
31 #include "helperFunctions.H"
32 #include "HashSet.H"
33 
34 #include <set>
35 
36 //#define DEBUGLayer
37 
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 
40 namespace Foam
41 {
42 
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 
46 {
47  if( !patchWiseLayers_ )
48  return;
49 
50  Info << "Checking topology of boundary faces" << endl;
51 
52  labelHashSet usedPatches;
53  forAll(patchLabels, i)
54  usedPatches.insert(patchLabels[i]);
55 
56  //- create a set of patch pairs. These are pairs at which the layers
57  //- shall be terminated
58  std::set<std::pair<label, label> > terminatedPairs;
60  {
61  const DynList<label>& otherPatches = treatPatchesWithPatch_[patchI];
62 
63  forAll(otherPatches, patchJ)
64  {
65  if( patchI == otherPatches[patchJ] )
66  continue;
67 
68  terminatedPairs.insert
69  (
70  std::make_pair
71  (
72  Foam::min(patchI, otherPatches[patchJ]),
73  Foam::max(patchI, otherPatches[patchJ])
74  )
75  );
76  }
77  }
78 
79  bool changed;
80  label nDecomposed(0);
81  boolList decomposeCell(mesh_.cells().size(), false);
82 
83  do
84  {
85  changed = false;
86 
87  const meshSurfaceEngine& mse = this->surfaceEngine();
88  const faceList::subList& bFaces = mse.boundaryFaces();
89  const labelList& faceOwner = mse.faceOwners();
90  const labelList& facePatches = mse.boundaryFacePatches();
91  const VRWGraph& faceEdges = mse.faceEdges();
92  const VRWGraph& edgeFaces = mse.edgeFaces();
93 
94  const Map<label>& otherProcPatch = mse.otherEdgeFacePatch();
95 
96  VRWGraph newBoundaryFaces;
97  labelLongList newBoundaryOwners;
98  labelLongList newBoundaryPatches;
99 
100  forAll(bFaces, bfI)
101  {
102  const face& bf = bFaces[bfI];
103  const label fPatch = facePatches[bfI];
104 
105  if( !usedPatches.found(fPatch) )
106  continue;
107 
108  //- find patches of neighbour faces
109  labelList neiPatches(bf.size());
110  forAll(bf, eI)
111  {
112  const label beI = faceEdges(bfI, eI);
113 
114  if( edgeFaces.sizeOfRow(beI) == 2 )
115  {
116  label neiFace = edgeFaces(beI, 0);
117  if( neiFace == bfI )
118  neiFace = edgeFaces(beI, 1);
119 
120  neiPatches[eI] = facePatches[neiFace];
121  }
122  else if( edgeFaces.sizeOfRow(beI) == 1 )
123  {
124  //- edge is at a parallel boundary
125  neiPatches[eI] = otherProcPatch[beI];
126  }
127  }
128 
129  //- find feature edges and check if the patches meeting there
130  //- shall be treated together.
131  bool storedFace(false);
132  forAll(neiPatches, eI)
133  {
134  if( neiPatches[eI] == fPatch )
135  continue;
136 
137  std::pair<label, label> pp
138  (
139  Foam::min(fPatch, neiPatches[eI]),
140  Foam::max(fPatch, neiPatches[eI])
141  );
142 
143  if( terminatedPairs.find(pp) == terminatedPairs.end() )
144  continue;
145 
146  //- create a new face from this edge and the neighbouring edges
147  bool usePrev(false), useNext(false);
148  if( neiPatches[neiPatches.rcIndex(eI)] == fPatch )
149  {
150  usePrev = true;
151  }
152  else
153  {
154  std::pair<label, label> ppPrev
155  (
156  Foam::min(fPatch, neiPatches[neiPatches.rcIndex(eI)]),
157  Foam::max(fPatch, neiPatches[neiPatches.rcIndex(eI)])
158  );
159 
160  if( terminatedPairs.find(ppPrev) == terminatedPairs.end() )
161  usePrev = true;
162  }
163 
164  if( neiPatches[neiPatches.fcIndex(eI)] == fPatch )
165  {
166  useNext = true;
167  }
168  else
169  {
170  std::pair<label, label> ppNext
171  (
172  Foam::min(fPatch, neiPatches[neiPatches.fcIndex(eI)]),
173  Foam::max(fPatch, neiPatches[neiPatches.fcIndex(eI)])
174  );
175 
176  if( terminatedPairs.find(ppNext) == terminatedPairs.end() )
177  useNext = true;
178  }
179 
180  DynList<edge> removeEdges;
181  if( useNext && usePrev )
182  {
183  removeEdges.setSize(3);
184  removeEdges[0] = bf.faceEdge(neiPatches.rcIndex(eI));
185  removeEdges[1] = bf.faceEdge(eI);
186  removeEdges[2] = bf.faceEdge(neiPatches.fcIndex(eI));
187  }
188  else if( useNext )
189  {
190  removeEdges.setSize(2);
191  removeEdges[0] = bf.faceEdge(neiPatches.fcIndex(eI));
192  removeEdges[1] = bf.faceEdge(eI);
193  }
194  else if( usePrev )
195  {
196  removeEdges.setSize(2);
197  removeEdges[0] = bf.faceEdge(neiPatches.rcIndex(eI));
198  removeEdges[1] = bf.faceEdge(eI);
199  }
200 
201  const face cutFace = help::removeEdgesFromFace(bf, removeEdges);
202  if( cutFace.size() > 2 )
203  {
204  newBoundaryFaces.appendList(cutFace);
205  newBoundaryOwners.append(faceOwner[bfI]);
206  newBoundaryPatches.append(fPatch);
207  }
208  const face rFace = help::createFaceFromRemovedPart(bf, cutFace);
209  if( rFace.size() > 2 )
210  {
211  newBoundaryFaces.appendList(rFace);
212  newBoundaryOwners.append(faceOwner[bfI]);
213  newBoundaryPatches.append(fPatch);
214  }
215 
216  if( (cutFace.size() > 2) && (rFace.size() > 2) )
217  {
218  decomposeCell[faceOwner[bfI]] = true;
219  changed = true;
220  ++nDecomposed;
221  }
222 
223  storedFace = true;
224 
225  break;
226  }
227 
228  if( !storedFace )
229  {
230  newBoundaryFaces.appendList(bf);
231  newBoundaryOwners.append(faceOwner[bfI]);
232  newBoundaryPatches.append(fPatch);
233  }
234  }
235 
236  //- Finally, replace the boundary faces
237  reduce(changed, maxOp<bool>());
238 
239  if( changed )
240  {
241  polyMeshGenModifier meshModifier(mesh_);
242  meshModifier.replaceBoundary
243  (
244  patchNames_,
245  newBoundaryFaces,
246  newBoundaryOwners,
247  newBoundaryPatches
248  );
249 
250  PtrList<boundaryPatch>& boundaries =
251  meshModifier.boundariesAccess();
252  forAll(boundaries, patchI)
253  boundaries[patchI].patchType() = patchTypes_[patchI];
254 
255  clearOut();
256  }
257 
258  } while( changed );
259 
260  //- decompose owner cells adjacent to the decomposed faces
261  reduce(nDecomposed, sumOp<label>());
262 
263  if( nDecomposed != 0 )
264  {
265  FatalError << "Critical. Not tested" << exit(FatalError);
266  decomposeCells dc(mesh_);
267  dc.decomposeMesh(decomposeCell);
268 
269  clearOut();
270  }
271 
272  mesh_.write();
273  Info << "Finished checking topology" << endl;
274 }
275 
276 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
277 
278 } // End namespace Foam
279 
280 // ************************************************************************* //
Foam::maxOp
Definition: ops.H:172
Foam::LongList::append
void append(const T &e)
Append an element at the end of the list.
Definition: LongListI.H:265
Foam::boundaryLayers::patchNames_
wordList patchNames_
patch names
Definition: boundaryLayers.H:82
Foam::boundaryLayers::surfaceEngine
const meshSurfaceEngine & surfaceEngine() const
Return const reference to meshSurfaceEngine.
Definition: boundaryLayers.C:54
Foam::decomposeCells::decomposeMesh
void decomposeMesh(const boolList &)
perform decomposition of selected cell into pyramids
Definition: decomposeCellsDecomposition.C:42
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::boundaryLayers::mesh_
polyMeshGen & mesh_
Reference to the mesh.
Definition: boundaryLayers.H:63
Foam::boundaryLayers::patchTypes_
wordList patchTypes_
patch types
Definition: boundaryLayers.H:85
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:53
Foam::face::faceEdge
edge faceEdge(const label n) const
Return n-th face edge.
Definition: faceI.H:110
decomposeCells.H
Foam::meshSurfaceEngine::boundaryFacePatches
const labelList & boundaryFacePatches() const
patch label for each boundary face
Definition: meshSurfaceEngineI.H:123
Foam::meshSurfaceEngine::faceEdges
const VRWGraph & faceEdges() const
Definition: meshSurfaceEngineI.H:353
Foam::Map< label >
Foam::polyMeshGenModifier::replaceBoundary
void replaceBoundary(const wordList &patchNames, const VRWGraph &boundaryFaces, const labelLongList &faceOwners, const labelLongList &facePatches)
replace the boundary with new boundary faces
Definition: polyMeshGenModifierReplaceBoundary.C:42
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::help::createFaceFromRemovedPart
face createFaceFromRemovedPart(const face &fOrig, const face &fCut)
create a face from the removed part
Definition: helperFunctionsTopologyManipulationI.H:219
Foam::HashSet< label, Hash< label > >
Foam::polyMeshGenModifier::boundariesAccess
PtrList< boundaryPatch > & boundariesAccess()
access to boundary data
Definition: polyMeshGenModifier.H:131
Foam::LongList< label >
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::meshSurfaceEngine::boundaryFaces
const faceList::subList & boundaryFaces() const
Definition: meshSurfaceEngineI.H:103
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::polyMeshGenCells::cells
const cellListPMG & cells() const
access to cells
Definition: polyMeshGenCellsI.H:39
Foam::PtrList
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: List.H:61
Foam::help::removeEdgesFromFace
face removeEdgesFromFace(const face &fOrig, const DynList< edge > &removeEdges)
remove edges from face
Definition: helperFunctionsTopologyManipulationI.H:252
HashSet.H
Foam::VRWGraph::sizeOfRow
label sizeOfRow(const label rowI) const
Returns the number of elements in the given row.
Definition: VRWGraphI.H:127
Foam::FatalError
error FatalError
Foam::HashTable::found
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:109
Foam::meshSurfaceEngine::edgeFaces
const VRWGraph & edgeFaces() const
Definition: meshSurfaceEngineI.H:334
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
meshSurfaceEngine.H
Foam::DynList< label >
Foam::boundaryLayers::checkTopologyOfBoundaryFaces
void checkTopologyOfBoundaryFaces(const labelList &patchLabels)
Definition: boundaryLayersCheckTopologyOfBndFaces.C:45
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::boundaryLayers::clearOut
void clearOut()
delete meshSurfaceEngine
Definition: boundaryLayers.H:225
Foam::max
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::polyMeshGenModifier
Definition: polyMeshGenModifier.H:52
Foam::decomposeCells
Definition: decomposeCells.H:48
Foam::sumOp
Definition: ops.H:162
Foam::boundaryLayers::treatPatchesWithPatch_
List< DynList< label > > treatPatchesWithPatch_
extrude patches with patch
Definition: boundaryLayers.H:92
helperFunctions.H
Foam::VRWGraph::appendList
void appendList(const ListType &l)
Append a list as a row at the end of the graph.
Definition: VRWGraphI.H:286
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::polyMeshGen::write
void write() const
Definition: polyMeshGen.C:126
Foam::DynList::setSize
void setSize(const label)
Reset size of List.
Definition: DynListI.H:263
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:116
Foam::boundaryLayers::patchWiseLayers_
bool patchWiseLayers_
Definition: boundaryLayers.H:73
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::meshSurfaceEngine::otherEdgeFacePatch
const Map< label > & otherEdgeFacePatch() const
Definition: meshSurfaceEngineI.H:588
Foam::VRWGraph
Definition: VRWGraph.H:101
Foam::min
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
boundaryLayers.H
Foam::meshSurfaceEngine
Definition: meshSurfaceEngine.H:54
Foam::cellListPMG::size
label size() const
return the number of used elements
Definition: cellListPMGI.H:56
Foam::meshSurfaceEngine::faceOwners
const labelList & faceOwners() const
Definition: meshSurfaceEngineI.H:143