Loading...
Searching...
No Matches
removeCells.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2015-2018 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "removeCells.H"
30#include "bitSet.H"
31#include "polyMesh.H"
32#include "polyTopoChange.H"
33#include "polyRemoveCell.H"
34#include "polyRemoveFace.H"
35#include "polyModifyFace.H"
37#include "syncTools.H"
38
39// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
40
41namespace Foam
42{
44}
45
46// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
47
48namespace
49{
50
51// Increase count (usage) of elements of list
52inline void incrCount(const Foam::labelUList& list, Foam::labelList& counter)
53{
54 for (auto idx : list)
55 {
56 ++counter[idx];
57 }
58}
59
60// Decrease count (usage) of elements of list
61inline void decrCount(const Foam::labelUList& list, Foam::labelList& counter)
62{
63 for (auto idx : list)
64 {
65 --counter[idx];
66 }
68
69} // End anonymous namespace
70
71
72// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
73
74Foam::removeCells::removeCells(const polyMesh& mesh, const bool syncPar)
75:
76 mesh_(mesh),
77 syncPar_(syncPar)
78{}
79
80
81// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
82
84(
85 const bitSet& removedCell
86) const
87{
88 const labelList& faceOwner = mesh_.faceOwner();
89 const labelList& faceNeighbour = mesh_.faceNeighbour();
90
91 // Count cells using face.
92 labelList nCellsUsingFace(mesh_.nFaces(), Zero);
93
94 for (label facei = 0; facei < mesh_.nInternalFaces(); ++facei)
95 {
96 const label own = faceOwner[facei];
97 const label nei = faceNeighbour[facei];
98
99 if (!removedCell[own])
100 {
101 ++nCellsUsingFace[facei];
102 }
103 if (!removedCell[nei])
104 {
105 ++nCellsUsingFace[facei];
106 }
107 }
108
109 for (label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); ++facei)
110 {
111 const label own = faceOwner[facei];
112
113 if (!removedCell[own])
114 {
115 ++nCellsUsingFace[facei];
116 }
117 }
118
119 // Coupled faces: add number of cells using face across couple.
120 {
121 // Note cyclics done always, parallel bits only done if syncPar_
122
123 SubList<label> bndValues
124 (
125 nCellsUsingFace,
126 mesh_.nBoundaryFaces(),
127 mesh_.nInternalFaces()
128 );
129
131 (
132 mesh_,
133 bndValues,
134 plusEqOp<label>(),
135 mapDistribute::transform(),
136 syncPar_
137 );
138 }
139
140 // Now nCellsUsingFace:
141 // 0 : internal face whose both cells get deleted
142 // boundary face whose all cells get deleted
143 // 1 : internal face that gets exposed
144 // unaffected (uncoupled) boundary face
145 // coupled boundary face that gets exposed ('uncoupled')
146 // 2 : unaffected internal face
147 // unaffected coupled boundary face
148
149 DynamicList<label> exposedFaces(mesh_.nFaces()/10);
150
151 for (label facei = 0; facei < mesh_.nInternalFaces(); ++facei)
152 {
153 if (nCellsUsingFace[facei] == 1)
154 {
155 exposedFaces.append(facei);
156 }
157 }
158
159 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
160
161 for (const polyPatch& pp : patches)
162 {
163 if (pp.coupled())
164 {
165 label facei = pp.start();
166
167 forAll(pp, i)
168 {
169 const label own = faceOwner[facei];
170
171 if (nCellsUsingFace[facei] == 1 && !removedCell[own])
172 {
173 // My owner not removed but other side is so has to become
174 // normal, uncoupled, boundary face
175 exposedFaces.append(facei);
176 }
177
178 ++facei;
179 }
181 }
182
183 return labelList(std::move(exposedFaces));
184}
185
186
188(
189 const bitSet& removedCell,
190 const labelUList& exposedFaceLabels,
191 const labelUList& exposedPatchIDs,
192 polyTopoChange& meshMod
193) const
194{
195 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
196
197 if (exposedFaceLabels.size() != exposedPatchIDs.size())
198 {
200 << "Size of exposedFaceLabels " << exposedFaceLabels.size()
201 << " differs from size of exposedPatchIDs "
202 << exposedPatchIDs.size()
203 << abort(FatalError);
204 }
205
206 // List of new patchIDs
207 labelList newPatchID(mesh_.nFaces(), -1);
208
209 forAll(exposedFaceLabels, i)
210 {
211 const label facei = exposedFaceLabels[i];
212 const label patchi = exposedPatchIDs[i];
213
214 if (patchi < 0 || patchi >= patches.size())
215 {
217 << "Invalid patch " << patchi
218 << " for exposed face " << facei << nl
219 << "Valid patches 0.." << patches.size()-1
220 << abort(FatalError);
221 }
222
223 if (patches[patchi].coupled())
224 {
226 << "Trying to put exposed face " << facei
227 << " into a coupled patch : " << patches[patchi].name()
228 << nl
229 << "This is illegal."
230 << abort(FatalError);
231 }
232
233 newPatchID[facei] = patchi;
234 }
235
236
237 // Walk all the cells mentioned for removal
238 for (const label celli : removedCell)
239 {
240 //Pout<< "Removing cell " << celli
241 // << " cc:" << mesh_.cellCentres()[celli] << endl;
242
243 meshMod.setAction(polyRemoveCell(celli));
244 }
245
246
247 // Remove faces that are no longer used. Modify faces that
248 // are used by one cell only.
249
250 const faceList& faces = mesh_.faces();
251 const labelList& faceOwner = mesh_.faceOwner();
252 const labelList& faceNeighbour = mesh_.faceNeighbour();
253 const faceZoneMesh& faceZones = mesh_.faceZones();
254
255 // Count starting number of faces using each point.
256 // Update whenever removing a face.
257 labelList nFacesUsingPoint(mesh_.nPoints(), Zero);
258
259 for (const face& f : faces)
260 {
261 incrCount(f, nFacesUsingPoint);
262 }
263
264
265 for (label facei = 0; facei < mesh_.nInternalFaces(); ++facei)
266 {
267 const face& f = faces[facei];
268 const label own = faceOwner[facei];
269 const label nei = faceNeighbour[facei];
270
271 if (removedCell[own])
272 {
273 if (removedCell[nei])
274 {
275 // Face no longer used
276 //Pout<< "Removing internal face " << facei
277 // << " fc:" << mesh_.faceCentres()[facei] << endl;
278
279 meshMod.setAction(polyRemoveFace(facei));
280 decrCount(f, nFacesUsingPoint);
281 }
282 else
283 {
284 if (newPatchID[facei] == -1)
285 {
287 << "No patchID provided for exposed face " << facei
288 << " on cell " << nei << nl
289 << "Did you provide patch IDs for all exposed faces?"
290 << abort(FatalError);
291 }
292
293 // nei is remaining cell. Facei becomes external cell
294
295 const label zoneID = faceZones.whichZone(facei);
296 bool zoneFlip = false;
297
298 if (zoneID >= 0)
299 {
300 const faceZone& fZone = faceZones[zoneID];
301 // Note: we reverse the owner/neighbour of the face
302 // so should also select the other side of the zone
303 zoneFlip = !fZone.flipMap()[fZone.whichFace(facei)];
304 }
305
306 //Pout<< "Putting exposed internal face " << facei
307 // << " fc:" << mesh_.faceCentres()[facei]
308 // << " into patch " << newPatchID[facei] << endl;
309
310 meshMod.setAction
311 (
313 (
314 f.reverseFace(), // modified face
315 facei, // label of face being modified
316 nei, // owner
317 -1, // neighbour
318 true, // face flip
319 newPatchID[facei], // patch for face
320 false, // remove from zone
321 zoneID, // zone for face
322 zoneFlip // face flip in zone
323 )
324 );
325 }
326 }
327 else if (removedCell[nei])
328 {
329 if (newPatchID[facei] == -1)
330 {
332 << "No patchID provided for exposed face " << facei
333 << " on cell " << own << nl
334 << "Did you provide patch IDs for all exposed faces?"
335 << abort(FatalError);
336 }
337
338 //Pout<< "Putting exposed internal face " << facei
339 // << " fc:" << mesh_.faceCentres()[facei]
340 // << " into patch " << newPatchID[facei] << endl;
341
342 // own is remaining cell. Facei becomes external cell.
343 const label zoneID = faceZones.whichZone(facei);
344 bool zoneFlip = false;
345
346 if (zoneID >= 0)
347 {
348 const faceZone& fZone = faceZones[zoneID];
349 zoneFlip = fZone.flipMap()[fZone.whichFace(facei)];
350 }
351
352 meshMod.setAction
353 (
355 (
356 f, // modified face
357 facei, // label of face being modified
358 own, // owner
359 -1, // neighbour
360 false, // face flip
361 newPatchID[facei], // patch for face
362 false, // remove from zone
363 zoneID, // zone for face
364 zoneFlip // face flip in zone
365 )
366 );
367 }
368 }
369
370 for (const polyPatch& pp : patches)
371 {
372 if (pp.coupled())
373 {
374 label facei = pp.start();
375
376 forAll(pp, i)
377 {
378 if (newPatchID[facei] != -1)
379 {
380 //Pout<< "Putting uncoupled coupled face " << facei
381 // << " fc:" << mesh_.faceCentres()[facei]
382 // << " into patch " << newPatchID[facei] << endl;
383
384 const label zoneID = faceZones.whichZone(facei);
385 bool zoneFlip = false;
386
387 if (zoneID >= 0)
388 {
389 const faceZone& fZone = faceZones[zoneID];
390 zoneFlip = fZone.flipMap()[fZone.whichFace(facei)];
391 }
392
393 meshMod.setAction
394 (
396 (
397 faces[facei], // modified face
398 facei, // label of face
399 faceOwner[facei], // owner
400 -1, // neighbour
401 false, // face flip
402 newPatchID[facei], // patch for face
403 false, // remove from zone
404 zoneID, // zone for face
405 zoneFlip // face flip in zone
406 )
407 );
408 }
409 else if (removedCell[faceOwner[facei]])
410 {
411 // Face no longer used
412 //Pout<< "Removing boundary face " << facei
413 // << " fc:" << mesh_.faceCentres()[facei]
414 // << endl;
415
416 meshMod.setAction(polyRemoveFace(facei));
417 decrCount(faces[facei], nFacesUsingPoint);
418 }
419
420 ++facei;
421 }
422 }
423 else
424 {
425 label facei = pp.start();
426
427 forAll(pp, i)
428 {
429 if (newPatchID[facei] != -1)
430 {
432 << "new patchID provided for boundary face " << facei
433 << " even though it is not on a coupled face."
434 << abort(FatalError);
435 }
436
437 if (removedCell[faceOwner[facei]])
438 {
439 // Face no longer used
440 //Pout<< "Removing boundary face " << facei
441 // << " fc:" << mesh_.faceCentres()[facei]
442 // << endl;
443
444 meshMod.setAction(polyRemoveFace(facei));
445 decrCount(faces[facei], nFacesUsingPoint);
446 }
447
448 ++facei;
449 }
450 }
451 }
452
453
454 // Remove points that are no longer used.
455 // Loop rewritten to not use pointFaces.
456
457 forAll(nFacesUsingPoint, pointi)
458 {
459 if (nFacesUsingPoint[pointi] == 0)
460 {
461 //Pout<< "Removing unused point " << pointi
462 // << " at:" << mesh_.points()[pointi] << endl;
463
464 meshMod.setAction(polyRemovePoint(pointi));
465 }
466 else if (nFacesUsingPoint[pointi] == 1)
467 {
469 << "point " << pointi << " at coordinate "
470 << mesh_.points()[pointi]
471 << " is only used by 1 face after removing cells."
472 << " This probably results in an illegal mesh."
473 << endl;
474 }
475 }
476}
477
478
480(
481 const labelUList& cellsToRemove
482) const
484 bitSet removeCell(mesh_.nCells(), cellsToRemove);
485
486 return getExposedFaces(removeCell);
487}
488
489
491(
492 const labelUList& cellsToRemove,
493 const labelUList& exposedFaceLabels,
494 const labelUList& exposedPatchIDs,
495 polyTopoChange& meshMod
496) const
497{
498 bitSet removedCell(mesh_.nCells(), cellsToRemove);
499
500 setRefinement
501 (
502 removedCell,
503 exposedFaceLabels,
504 exposedPatchIDs,
505 meshMod
506 );
507}
508
509
510// ************************************************************************* //
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
void append(const T &val)
Copy append an element to the end of this list.
const word & name() const noexcept
Return the object name.
Definition IOobjectI.H:205
A non-owning sub-view of a List (allocated or unallocated storage).
Definition SubList.H:61
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
label size() const noexcept
The number of entries in the list.
Definition UPtrListI.H:106
label whichZone(const label objectIndex) const
Given a global object index, return the zone it is in.
Definition ZoneMesh.C:410
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition bitSet.H:61
A subset of mesh faces organised as a primitive patch.
Definition faceZone.H:63
label whichFace(const label meshFaceID) const
The local index of the given mesh face, -1 if not in the zone.
Definition faceZone.H:394
const boolList & flipMap() const noexcept
Return face flip map.
Definition faceZone.H:389
A face is a list of labels corresponding to mesh vertices.
Definition face.H:71
Default transformation behaviour.
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh,...
Mesh consisting of general polyhedral cells.
Definition polyMesh.H:79
virtual const labelList & faceOwner() const
Return face owner.
Definition polyMesh.C:1101
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition polyMesh.C:1107
Class describing modification of a face.
A patch is a list of labels that address the faces in the global face list.
Definition polyPatch.H:73
Class containing data for cell removal.
Class containing data for face removal.
Class containing data for point removal.
Direct mesh changes based on v1.3 polyTopoChange syntax.
label setAction(const topoAction &action)
For compatibility with polyTopoChange: set topological action.
label nInternalFaces() const noexcept
Number of internal faces.
label nFaces() const noexcept
Number of mesh faces.
Given list of cells to remove, insert all the topology changes.
Definition removeCells.H:60
labelList getExposedFaces(const bitSet &removedCell) const
Get labels of faces exposed after cells removal.
Definition removeCells.C:77
removeCells(const polyMesh &mesh, const bool syncPar=true)
Construct from mesh. Parallel synchronized by default.
Definition removeCells.C:67
void setRefinement(const bitSet &removedCell, const labelUList &facesToExpose, const labelUList &patchIDs, polyTopoChange &) const
Play commands into polyTopoChange to remove cells.
static void syncBoundaryFaceList(const polyMesh &mesh, UList< T > &faceValues, const CombineOp &cop, const TransformOp &top, const bool parRun=UPstream::parRun())
Synchronize values on boundary faces only.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
const polyBoundaryMesh & patches
bool coupled
dynamicFvMesh & mesh
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for OpenFOAM.
List< label > labelList
A List of labels.
Definition List.H:62
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with faceZone content on a polyMesh.
List< face > faceList
List of faces.
Definition faceListFwd.H:41
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
errorManip< error > abort(error &err)
Definition errorManip.H:139
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
UList< label > labelUList
A UList of labels.
Definition UList.H:75
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
labelList f(nPoints)
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299