50void Foam::polyMeshFilter::updateSets(
const mapPolyMesh& map)
52 updateSets<pointSet>(map);
53 updateSets<faceSet>(map);
54 updateSets<cellSet>(map);
58void Foam::polyMeshFilter::copySets
64 copySets<pointSet>(oldMesh, newMesh);
65 copySets<faceSet>(oldMesh, newMesh);
66 copySets<cellSet>(oldMesh, newMesh);
81 mesh.polyMesh::instance(),
94 meshCopy().updateMesh(map);
100 copySets(
mesh, meshCopy());
108Foam::label Foam::polyMeshFilter::filterFacesLoop(
const label nOriginalBadFaces)
111 label nOuterIterations = 0;
116 bitSet newErrorPoint(mesh_.nPoints());
120 meshQualityCoeffDict(),
124 bool newBadFaces =
true;
134 nOuterIterations < maxIterations()
139 Info<<
nl <<
"Outer Iteration = " << nOuterIterations++ <<
nl
142 printScalarFieldStats(
"Edge Filter Factor", minEdgeLen_);
143 printScalarFieldStats(
"Face Filter Factor", faceFilterFactor_);
146 newMeshPtr_ = copyMesh(mesh_);
147 fvMesh& newMesh = newMeshPtr_();
149 scalarField newMeshFaceFilterFactor = faceFilterFactor_;
150 pointPriority_.reset(
new labelList(originalPointPriority_));
155 label nInnerIterations = 0;
156 label nPrevLocalCollapse =
labelMax;
165 label nLocalCollapse = filterFaces
168 newMeshFaceFilterFactor,
169 origToCurrentPointMap
175 nLocalCollapse >= nPrevLocalCollapse
176 || nLocalCollapse == 0
184 nPrevLocalCollapse = nLocalCollapse;
192 label nInnerIterations = 0;
193 label nPrevLocalCollapse =
labelMax;
202 label nLocalCollapse = filterEdges
206 origToCurrentPointMap
212 nLocalCollapse >= nPrevLocalCollapse
213 || nLocalCollapse == 0
221 nPrevLocalCollapse = nLocalCollapse;
232 if (controlMeshQuality())
234 bitSet isErrorPoint(newMesh.nPoints());
238 meshQualityCoeffDict(),
242 Info<<
nl <<
" Number of bad faces : " << nBadFaces <<
nl
243 <<
" Number of marked points : "
247 updatePointErrorCount
250 origToCurrentPointMap,
254 checkMeshEdgesAndRelaxEdges
257 origToCurrentPointMap,
262 checkMeshFacesAndRelaxEdges
265 origToCurrentPointMap,
271 forAll(mesh_.points(), pI)
275 origToCurrentPointMap[pI] >= 0
276 && isErrorPoint[origToCurrentPointMap[pI]]
279 if (!newErrorPoint[pI])
299Foam::label Foam::polyMeshFilter::filterFaces
309 Map<point> collapsePointToLocation(newMesh.nPoints());
315 labelPair nCollapsedPtEdge = collapser.markSmallSliverFaces
317 newMeshFaceFilterFactor,
320 collapsePointToLocation
323 label nCollapsed = 0;
324 forAll(nCollapsedPtEdge, collapseTypeI)
326 nCollapsed += nCollapsedPtEdge[collapseTypeI];
335 <<
"Collapsing " << nCollapsed <<
" faces "
336 <<
"(to point = " << nToPoint <<
", to edge = " << nToEdge <<
")"
350 collapser.consistentCollapse
354 collapsePointToLocation,
363 <<
" edges after synchronisation and PointEdgeWave" <<
endl;
365 if (nLocalCollapse == 0)
375 collapser.setRefinement(allPointInfo, newMeshMod);
388 newMesh.updateMesh(newMap);
389 if (newMap.hasMotionPoints())
391 newMesh.movePoints(newMap.preMotionPoints());
395 updatePointPriorities(newMesh, newMap.pointMap());
397 mapOldMeshFaceFieldToNewMesh
401 newMeshFaceFilterFactor
404 updateOldToNewPointMap
406 newMap.reversePointMap(),
407 origToCurrentPointMap
411 return nLocalCollapse;
415Foam::label Foam::polyMeshFilter::filterEdges
425 Map<point> collapsePointToLocation(newMesh.nPoints());
433 label nSmallCollapsed = collapser.markSmallEdges
438 collapsePointToLocation
442 Info<<
indent <<
"Collapsing " << nSmallCollapsed
443 <<
" small edges" <<
endl;
446 label nMerged = collapser.markMergeEdges
451 collapsePointToLocation
455 Info<<
indent <<
"Collapsing " << nMerged <<
" in line edges"
458 if (nMerged + nSmallCollapsed == 0)
468 collapser.consistentCollapse
472 collapsePointToLocation,
481 <<
" edges after synchronisation and PointEdgeWave" <<
endl;
483 if (nLocalCollapse == 0)
492 collapser.setRefinement(allPointInfo, newMeshMod);
505 newMesh.updateMesh(newMap);
506 if (newMap.hasMotionPoints())
508 newMesh.movePoints(newMap.preMotionPoints());
513 mapOldMeshEdgeFieldToNewMesh
520 updateOldToNewPointMap
522 newMap.reversePointMap(),
523 origToCurrentPointMap
526 updatePointPriorities(newMesh, newMap.pointMap());
528 return nLocalCollapse;
532void Foam::polyMeshFilter::updatePointErrorCount
534 const bitSet& isErrorPoint,
539 forAll(mesh_.points(), pI)
541 if (isErrorPoint[oldToNewMesh[pI]])
543 pointErrorCount[pI]++;
549void Foam::polyMeshFilter::checkMeshEdgesAndRelaxEdges
553 const bitSet& isErrorPoint,
557 const edgeList& edges = mesh_.edges();
561 const edge&
e = edges[edgeI];
562 label newStart = oldToNewMesh[
e[0]];
563 label newEnd = oldToNewMesh[
e[1]];
567 pointErrorCount[
e[0]] >= maxPointErrorCount()
568 || pointErrorCount[
e[1]] >= maxPointErrorCount()
571 minEdgeLen_[edgeI] = -1;
576 (newStart >= 0 && isErrorPoint[newStart])
577 || (newEnd >= 0 && isErrorPoint[newEnd])
580 minEdgeLen_[edgeI] *= edgeReductionFactor();
586 for (label smoothIter = 0; smoothIter < maxSmoothIters(); ++smoothIter)
589 forAll(mesh_.edges(), edgeI)
591 const edge&
e = mesh_.edges()[edgeI];
593 scalar sumMinEdgeLen = 0;
598 const labelList& pEdges = mesh_.pointEdges()[
e[pointi]];
602 const label pEdge = pEdges[pEdgeI];
603 sumMinEdgeLen += minEdgeLen_[pEdge];
608 minEdgeLen_[edgeI] =
min
626void Foam::polyMeshFilter::checkMeshFacesAndRelaxEdges
630 const bitSet& isErrorPoint,
634 const faceList& faces = mesh_.faces();
638 const face&
f = faces[facei];
642 const label ptIndex = oldToNewMesh[
f[fpI]];
644 if (pointErrorCount[
f[fpI]] >= maxPointErrorCount())
646 faceFilterFactor_[facei] = -1;
649 if (isErrorPoint[ptIndex])
651 faceFilterFactor_[facei] *= faceReductionFactor();
660 for (label smoothIter = 0; smoothIter < maxSmoothIters(); ++smoothIter)
665 const labelList& fEdges = mesh_.faceEdges()[facei];
667 scalar sumFaceFilterFactors = 0;
672 bool skipFace =
true;
676 const labelList& eFaces = mesh_.edgeFaces()[fEdges[fEdgeI]];
680 const label eFace = eFaces[eFacei];
682 const face&
f = faces[eFace];
686 const label ptIndex = oldToNewMesh[
f[fpI]];
688 if (isErrorPoint[ptIndex])
697 sumFaceFilterFactors += faceFilterFactor_[eFace];
708 faceFilterFactor_[facei] =
min
710 faceFilterFactor_[facei],
711 sumFaceFilterFactors/nFaces
721void Foam::polyMeshFilter::updatePointPriorities
728 const labelList& currPointPriority = pointPriority_();
730 forAll(newPointPriority, ptI)
732 const label newPointToOldPoint = pointMap[ptI];
733 const label origPointPriority = currPointPriority[newPointToOldPoint];
735 newPointPriority[ptI] =
max(origPointPriority, newPointPriority[ptI]);
746 pointPriority_.reset(
new labelList(newPointPriority));
750void Foam::polyMeshFilter::printScalarFieldStats
757 scalar validElements = 0;
763 const scalar fldElement =
fld[i];
769 if (fldElement <
min)
774 if (fldElement >
max)
791 <<
" av = " <<
sum/(validElements + SMALL)
792 <<
" max = " <<
max <<
nl
794 <<
" " << validElements <<
" / " << totFieldSize <<
" elements used"
799void Foam::polyMeshFilter::mapOldMeshEdgeFieldToNewMesh
808 const edgeList& newEdges = newMesh.edges();
810 forAll(newEdges, newEdgeI)
812 const edge& newEdge = newEdges[newEdgeI];
813 const label pStart = newEdge.
start();
814 const label pEnd = newEdge.end();
818 newMeshMinEdgeLen[pointMap[pStart]],
819 newMeshMinEdgeLen[pointMap[pEnd]]
823 newMeshMinEdgeLen.transfer(
tmp);
835void Foam::polyMeshFilter::mapOldMeshFaceFieldToNewMesh
846 const label oldFacei =
faceMap[newFacei];
848 tmp[newFacei] = newMeshFaceFilterFactor[oldFacei];
851 newMeshFaceFilterFactor.transfer(
tmp);
856 newMeshFaceFilterFactor,
862void Foam::polyMeshFilter::updateOldToNewPointMap
868 forAll(origToCurrentPointMap, origPointi)
870 label oldPointi = origToCurrentPointMap[origPointi];
878 origToCurrentPointMap[origPointi] =
newPointi;
882 origToCurrentPointMap[origPointi] = -1;
886 origToCurrentPointMap[origPointi] = -
newPointi-2;
895Foam::polyMeshFilter::polyMeshFilter(
const fvMesh&
mesh)
922Foam::polyMeshFilter::polyMeshFilter
944 originalPointPriority_(pointPriority),
952Foam::polyMeshFilter::polyMeshFilter
962 originalPointPriority_(pointPriority),
975 minEdgeLen_.resize(mesh_.nEdges(),
minLen());
978 return filterFacesLoop(nOriginalBadFaces);
984 minEdgeLen_.resize(mesh_.nEdges(), minLen());
985 faceFilterFactor_.resize(mesh_.nFaces(), initialFaceLengthFactor());
987 forAll(faceFilterFactor_, fI)
991 faceFilterFactor_[fI] = -1;
995 return filterFacesLoop(0);
999Foam::label Foam::polyMeshFilter::filterEdges
1001 const label nOriginalBadFaces
1005 label nPreviousBadFaces =
labelMax;
1006 label nOuterIterations = 0;
1008 minEdgeLen_.resize(mesh_.nEdges(), minLen());
1009 faceFilterFactor_.clear();
1021 nOuterIterations < maxIterations()
1022 && nBadFaces > nOriginalBadFaces
1023 && nBadFaces < nPreviousBadFaces
1026 Info<<
nl <<
"Outer Iteration = " << nOuterIterations++ <<
nl
1029 printScalarFieldStats(
"Edge Filter Factor", minEdgeLen_);
1031 nPreviousBadFaces = nBadFaces;
1034 newMeshPtr_ = copyMesh(mesh_);
1035 fvMesh& newMesh = newMeshPtr_();
1038 pointPriority_.reset(
new labelList(originalPointPriority_));
1044 label nInnerIterations = 0;
1045 label nPrevLocalCollapse =
labelMax;
1050 <<
indent <<
"Inner iteration = " << nInnerIterations++ <<
nl
1053 label nLocalCollapse = filterEdges
1057 origToCurrentPointMap
1064 nLocalCollapse >= nPrevLocalCollapse
1065 || nLocalCollapse == 0
1073 nPrevLocalCollapse = nLocalCollapse;
1082 if (controlMeshQuality())
1084 bitSet isErrorPoint(newMesh.nPoints());
1088 meshQualityCoeffDict(),
1092 Info<<
nl <<
" Number of bad faces : " << nBadFaces <<
nl
1093 <<
" Number of marked points : "
1097 updatePointErrorCount
1100 origToCurrentPointMap,
1104 checkMeshEdgesAndRelaxEdges
1107 origToCurrentPointMap,
1131 return pointPriority_;
Info<< nl;Info<< "Write faMesh in vtk format:"<< nl;{ vtk::uindirectPatchWriter writer(aMesh.patch(), fileName(aMesh.time().globalPath()/vtkBaseFileName));writer.writeGeometry();globalIndex procAddr(aMesh.nFaces());labelList cellIDs;if(UPstream::master()) { cellIDs.resize(procAddr.totalSize());for(const labelRange &range :procAddr.ranges()) { auto slice=cellIDs.slice(range);slice=identity(range);} } writer.beginCellData(4);writer.writeProcIDs();writer.write("cellID", cellIDs);writer.write("area", aMesh.S().field());writer.write("normal", aMesh.faceAreaNormals());writer.beginPointData(1);writer.write("normal", aMesh.pointAreaNormals());Info<< " "<< writer.output().name()<< nl;}{ vtk::lineWriter writer(aMesh.points(), aMesh.edges(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edges")));writer.writeGeometry();writer.beginCellData(4);writer.writeProcIDs();{ Field< scalar > fld(faMeshTools::flattenEdgeField(aMesh.magLe(), true))
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
@ NO_REGISTER
Do not request registration (bool: false).
@ READ_IF_PRESENT
Reading is optional [identical to LAZY_READ].
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
A HashTable to objects of type <T> with a label key.
static void reduceOr(bool &value, const int communicator=worldComm)
Logical (or) reduction (MPI_AllReduce).
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
unsigned int count(const bool on=true) const
Count number of bits set.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Does polyTopoChanges to remove edges. Can remove faces due to edge collapse but can not remove cells ...
static label checkMeshQuality(const polyMesh &mesh, const dictionary &meshQualityDict, bitSet &isErrorPoint)
Check mesh and mark points on faces in error.
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
label start() const noexcept
The start (first) vertex label.
A face is a list of labels corresponding to mesh vertices.
Mesh data needed to do the Finite Volume discretisation.
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
Calculates points shared by more than two processor patches or cyclic patches.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
const pointField & preMotionPoints() const noexcept
Pre-motion point positions.
bool hasMotionPoints() const noexcept
Has valid preMotionPoints?
Class to store the settings for the polyMeshFilter class.
const scalar & minLen() const
polyMeshFilterSettings(const dictionary &dict)
Construct from dictionary.
void writeSettings(Ostream &os) const
Write the settings to a stream.
Switch controlMeshQuality() const
const label & maxIterations() const
const scalar & initialFaceLengthFactor() const
const dictionary & meshQualityCoeffDict() const
Remove the edges and faces of a polyMesh whilst satisfying the given mesh quality criteria.
const autoPtr< labelList > & pointPriority() const
Return the new pointPriority list.
label filter(const label nOriginalBadFaces)
Filter edges and faces.
static autoPtr< fvMesh > copyMesh(const fvMesh &mesh)
Return a copy of an fvMesh.
const autoPtr< fvMesh > & filteredMesh() const
Return reference to the filtered mesh. Does not check if the.
Mesh consisting of general polyhedral cells.
Direct mesh changes based on v1.3 polyTopoChange syntax.
autoPtr< mapPolyMesh > makeMesh(autoPtr< Type > &newMesh, const IOobject &io, const polyMesh &mesh, const labelUList &patchMap, const bool syncParallel=true, const bool orderCells=false, const bool orderPoints=false)
Create new mesh with old mesh patches. Additional dictionaries.
label nPoints() const noexcept
Number of mesh points.
A class for managing temporary objects.
virtual bool found(const label id) const
Has the given index?
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
label collapseEdge(triSurface &surf, const scalar minLen)
Keep collapsing all edges < minLen.
List< edge > edgeList
List of edge.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Pair< label > labelPair
A pair of labels.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
int system(const std::string &command, const bool bg=false)
Execute the specified command via the shell.
List< label > labelList
A List of labels.
messageStream Info
Information stream (stdout output on master, null elsewhere).
List< face > faceList
List of faces.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
T returnReduce(const T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Ostream & indent(Ostream &os)
Indent stream.
void reduce(T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce).
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1, const label comm)
static constexpr const zero Zero
Global zero (0).
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
constexpr char nl
The newline '\n' character (0x0a).
#define forAll(list, i)
Loop across all elements in list.
Unit conversion functions.