51 updateSets<pointSet>(map);
52 updateSets<faceSet>(map);
53 updateSets<cellSet>(map);
57void Foam::polyMeshFilter::copySets
63 copySets<pointSet>(oldMesh, newMesh);
64 copySets<faceSet>(oldMesh, newMesh);
65 copySets<cellSet>(oldMesh, newMesh);
80 mesh.polyMesh::instance(),
93 meshCopy().updateMesh(map);
99 copySets(
mesh, meshCopy());
107Foam::label Foam::polyMeshFilter::filterFacesLoop(
const label nOriginalBadFaces)
110 label nOuterIterations = 0;
115 bitSet newErrorPoint(mesh_.nPoints());
119 meshQualityCoeffDict(),
123 bool newBadFaces =
true;
133 nOuterIterations < maxIterations()
138 Info<<
nl <<
"Outer Iteration = " << nOuterIterations++ <<
nl
141 printScalarFieldStats(
"Edge Filter Factor", minEdgeLen_);
142 printScalarFieldStats(
"Face Filter Factor", faceFilterFactor_);
145 newMeshPtr_ = copyMesh(mesh_);
146 fvMesh& newMesh = newMeshPtr_();
148 scalarField newMeshFaceFilterFactor = faceFilterFactor_;
149 pointPriority_.reset(
new labelList(originalPointPriority_));
154 label nInnerIterations = 0;
155 label nPrevLocalCollapse =
labelMax;
164 label nLocalCollapse = filterFaces
167 newMeshFaceFilterFactor,
168 origToCurrentPointMap
174 nLocalCollapse >= nPrevLocalCollapse
175 || nLocalCollapse == 0
183 nPrevLocalCollapse = nLocalCollapse;
191 label nInnerIterations = 0;
192 label nPrevLocalCollapse =
labelMax;
201 label nLocalCollapse = filterEdges
205 origToCurrentPointMap
211 nLocalCollapse >= nPrevLocalCollapse
212 || nLocalCollapse == 0
220 nPrevLocalCollapse = nLocalCollapse;
231 if (controlMeshQuality())
233 bitSet isErrorPoint(newMesh.
nPoints());
237 meshQualityCoeffDict(),
241 Info<<
nl <<
" Number of bad faces : " << nBadFaces <<
nl
242 <<
" Number of marked points : "
243 <<
returnReduce(isErrorPoint.count(), sumOp<unsigned int>())
246 updatePointErrorCount
249 origToCurrentPointMap,
253 checkMeshEdgesAndRelaxEdges
256 origToCurrentPointMap,
261 checkMeshFacesAndRelaxEdges
264 origToCurrentPointMap,
270 forAll(mesh_.points(), pI)
274 origToCurrentPointMap[pI] >= 0
275 && isErrorPoint[origToCurrentPointMap[pI]]
278 if (!newErrorPoint[pI])
286 reduce(newBadFaces, orOp<bool>());
308 Map<point> collapsePointToLocation(newMesh.nPoints());
310 edgeCollapser collapser(newMesh, collapseFacesCoeffDict());
314 labelPair nCollapsedPtEdge = collapser.markSmallSliverFaces
316 newMeshFaceFilterFactor,
319 collapsePointToLocation
322 label nCollapsed = 0;
323 forAll(nCollapsedPtEdge, collapseTypeI)
325 nCollapsed += nCollapsedPtEdge[collapseTypeI];
328 reduce(nCollapsed, sumOp<label>());
330 label nToPoint =
returnReduce(nCollapsedPtEdge.first(), sumOp<label>());
331 label nToEdge =
returnReduce(nCollapsedPtEdge.second(), sumOp<label>());
334 <<
"Collapsing " << nCollapsed <<
" faces "
335 <<
"(to point = " << nToPoint <<
", to edge = " << nToEdge <<
")"
346 List<pointEdgeCollapse> allPointInfo;
347 const globalIndex globalPoints(newMesh.nPoints());
349 collapser.consistentCollapse
353 collapsePointToLocation,
360 reduce(nLocalCollapse, sumOp<label>());
362 <<
" edges after synchronisation and PointEdgeWave" <<
endl;
364 if (nLocalCollapse == 0)
371 polyTopoChange newMeshMod(newMesh);
374 collapser.setRefinement(allPointInfo, newMeshMod);
379 autoPtr<mapPolyMesh> newMapPtr = newMeshMod.changeMesh
384 const mapPolyMesh& newMap = newMapPtr();
387 newMesh.updateMesh(newMap);
388 if (newMap.hasMotionPoints())
390 newMesh.movePoints(newMap.preMotionPoints());
394 updatePointPriorities(newMesh, newMap.pointMap());
396 mapOldMeshFaceFieldToNewMesh
400 newMeshFaceFilterFactor
403 updateOldToNewPointMap
405 newMap.reversePointMap(),
406 origToCurrentPointMap
410 return nLocalCollapse;
424 Map<point> collapsePointToLocation(newMesh.nPoints());
426 edgeCollapser collapser(newMesh, collapseFacesCoeffDict());
432 label nSmallCollapsed = collapser.markSmallEdges
437 collapsePointToLocation
440 reduce(nSmallCollapsed, sumOp<label>());
441 Info<<
indent <<
"Collapsing " << nSmallCollapsed
442 <<
" small edges" <<
endl;
445 label nMerged = collapser.markMergeEdges
450 collapsePointToLocation
453 reduce(nMerged, sumOp<label>());
454 Info<<
indent <<
"Collapsing " << nMerged <<
" in line edges"
457 if (nMerged + nSmallCollapsed == 0)
464 List<pointEdgeCollapse> allPointInfo;
465 const globalIndex globalPoints(newMesh.nPoints());
467 collapser.consistentCollapse
471 collapsePointToLocation,
478 reduce(nLocalCollapse, sumOp<label>());
480 <<
" edges after synchronisation and PointEdgeWave" <<
endl;
482 if (nLocalCollapse == 0)
488 polyTopoChange newMeshMod(newMesh);
491 collapser.setRefinement(allPointInfo, newMeshMod);
496 autoPtr<mapPolyMesh> newMapPtr = newMeshMod.changeMesh
501 const mapPolyMesh& newMap = newMapPtr();
504 newMesh.updateMesh(newMap);
505 if (newMap.hasMotionPoints())
507 newMesh.movePoints(newMap.preMotionPoints());
512 mapOldMeshEdgeFieldToNewMesh
519 updateOldToNewPointMap
521 newMap.reversePointMap(),
522 origToCurrentPointMap
525 updatePointPriorities(newMesh, newMap.pointMap());
527 return nLocalCollapse;
531void Foam::polyMeshFilter::updatePointErrorCount
533 const bitSet& isErrorPoint,
538 forAll(mesh_.points(), pI)
540 if (isErrorPoint[oldToNewMesh[pI]])
542 pointErrorCount[pI]++;
548void Foam::polyMeshFilter::checkMeshEdgesAndRelaxEdges
550 const polyMesh& newMesh,
552 const bitSet& isErrorPoint,
556 const edgeList& edges = mesh_.edges();
560 const edge&
e = edges[edgeI];
561 label newStart = oldToNewMesh[
e[0]];
562 label newEnd = oldToNewMesh[
e[1]];
566 pointErrorCount[
e[0]] >= maxPointErrorCount()
567 || pointErrorCount[
e[1]] >= maxPointErrorCount()
570 minEdgeLen_[edgeI] = -1;
575 (newStart >= 0 && isErrorPoint[newStart])
576 || (newEnd >= 0 && isErrorPoint[newEnd])
579 minEdgeLen_[edgeI] *= edgeReductionFactor();
585 for (label smoothIter = 0; smoothIter < maxSmoothIters(); ++smoothIter)
588 forAll(mesh_.edges(), edgeI)
590 const edge&
e = mesh_.edges()[edgeI];
592 scalar sumMinEdgeLen = 0;
597 const labelList& pEdges = mesh_.pointEdges()[
e[pointi]];
601 const label pEdge = pEdges[pEdgeI];
602 sumMinEdgeLen += minEdgeLen_[pEdge];
607 minEdgeLen_[edgeI] =
min
625void Foam::polyMeshFilter::checkMeshFacesAndRelaxEdges
627 const polyMesh& newMesh,
629 const bitSet& isErrorPoint,
633 const faceList& faces = mesh_.faces();
637 const face&
f = faces[facei];
641 const label ptIndex = oldToNewMesh[
f[fpI]];
643 if (pointErrorCount[
f[fpI]] >= maxPointErrorCount())
645 faceFilterFactor_[facei] = -1;
648 if (isErrorPoint[ptIndex])
650 faceFilterFactor_[facei] *= faceReductionFactor();
659 for (label smoothIter = 0; smoothIter < maxSmoothIters(); ++smoothIter)
664 const labelList& fEdges = mesh_.faceEdges()[facei];
666 scalar sumFaceFilterFactors = 0;
671 bool skipFace =
true;
675 const labelList& eFaces = mesh_.edgeFaces()[fEdges[fEdgeI]];
679 const label eFace = eFaces[eFacei];
681 const face&
f = faces[eFace];
685 const label ptIndex = oldToNewMesh[
f[fpI]];
687 if (isErrorPoint[ptIndex])
696 sumFaceFilterFactors += faceFilterFactor_[eFace];
707 faceFilterFactor_[facei] =
min
709 faceFilterFactor_[facei],
710 sumFaceFilterFactors/
nFaces
720void Foam::polyMeshFilter::updatePointPriorities
722 const polyMesh& newMesh,
727 const labelList& currPointPriority = pointPriority_();
729 forAll(newPointPriority, ptI)
731 const label newPointToOldPoint = pointMap[ptI];
732 const label origPointPriority = currPointPriority[newPointToOldPoint];
734 newPointPriority[ptI] =
max(origPointPriority, newPointPriority[ptI]);
745 pointPriority_.reset(
new labelList(newPointPriority));
749void Foam::polyMeshFilter::printScalarFieldStats
756 scalar validElements = 0;
762 const scalar fldElement =
fld[i];
768 if (fldElement <
min)
773 if (fldElement >
max)
785 reduce(validElements, sumOp<label>());
790 <<
" av = " <<
sum/(validElements + SMALL)
791 <<
" max = " <<
max <<
nl
793 <<
" " << validElements <<
" / " << totFieldSize <<
" elements used"
798void Foam::polyMeshFilter::mapOldMeshEdgeFieldToNewMesh
800 const polyMesh& newMesh,
807 const edgeList& newEdges = newMesh.edges();
809 forAll(newEdges, newEdgeI)
811 const edge& newEdge = newEdges[newEdgeI];
812 const label pStart = newEdge.start();
813 const label pEnd = newEdge.end();
817 newMeshMinEdgeLen[pointMap[pStart]],
818 newMeshMinEdgeLen[pointMap[pEnd]]
822 newMeshMinEdgeLen.transfer(tmp);
834void Foam::polyMeshFilter::mapOldMeshFaceFieldToNewMesh
836 const polyMesh& newMesh,
845 const label oldFacei =
faceMap[newFacei];
847 tmp[newFacei] = newMeshFaceFilterFactor[oldFacei];
850 newMeshFaceFilterFactor.transfer(tmp);
855 newMeshFaceFilterFactor,
861void Foam::polyMeshFilter::updateOldToNewPointMap
867 forAll(origToCurrentPointMap, origPointi)
869 label oldPointi = origToCurrentPointMap[origPointi];
877 origToCurrentPointMap[origPointi] =
newPointi;
881 origToCurrentPointMap[origPointi] = -1;
885 origToCurrentPointMap[origPointi] = -
newPointi-2;
943 originalPointPriority_(pointPriority),
961 originalPointPriority_(pointPriority),
974 minEdgeLen_.resize(mesh_.nEdges(), minLen());
975 faceFilterFactor_.resize(mesh_.nFaces(), initialFaceLengthFactor());
977 return filterFacesLoop(nOriginalBadFaces);
983 minEdgeLen_.resize(mesh_.nEdges(), minLen());
984 faceFilterFactor_.resize(mesh_.nFaces(), initialFaceLengthFactor());
986 forAll(faceFilterFactor_, fI)
990 faceFilterFactor_[fI] = -1;
994 return filterFacesLoop(0);
1000 const label nOriginalBadFaces
1004 label nPreviousBadFaces =
labelMax;
1005 label nOuterIterations = 0;
1007 minEdgeLen_.resize(mesh_.nEdges(), minLen());
1008 faceFilterFactor_.resize(0);
1020 nOuterIterations < maxIterations()
1021 && nBadFaces > nOriginalBadFaces
1022 && nBadFaces < nPreviousBadFaces
1025 Info<<
nl <<
"Outer Iteration = " << nOuterIterations++ <<
nl
1028 printScalarFieldStats(
"Edge Filter Factor", minEdgeLen_);
1030 nPreviousBadFaces = nBadFaces;
1033 newMeshPtr_ = copyMesh(mesh_);
1034 fvMesh& newMesh = newMeshPtr_();
1037 pointPriority_.reset(
new labelList(originalPointPriority_));
1043 label nInnerIterations = 0;
1044 label nPrevLocalCollapse =
labelMax;
1049 <<
indent <<
"Inner iteration = " << nInnerIterations++ <<
nl
1052 label nLocalCollapse = filterEdges
1056 origToCurrentPointMap
1063 nLocalCollapse >= nPrevLocalCollapse
1064 || nLocalCollapse == 0
1072 nPrevLocalCollapse = nLocalCollapse;
1081 if (controlMeshQuality())
1087 meshQualityCoeffDict(),
1091 Info<<
nl <<
" Number of bad faces : " << nBadFaces <<
nl
1092 <<
" Number of marked points : "
1096 updatePointErrorCount
1099 origToCurrentPointMap,
1103 checkMeshEdgesAndRelaxEdges
1106 origToCurrentPointMap,
1130 return pointPriority_;
Info<< nl<< "Wrote faMesh in vtk format: "<< writer.output().name()<< nl;}{ vtk::lineWriter writer(aMesh.points(), aMesh.edges(), fileName(aMesh.mesh().time().globalPath()/"finiteArea-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...
Defines the attributes of an object for which implicit objectRegistry management is supported,...
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.
Switch filterFaces() const
Filter faces at output time.
Switch filterEdges() const
Filter edges at output time.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
static label checkMeshQuality(const polyMesh &mesh, const dictionary &meshQualityDict, bitSet &isErrorPoint)
Check mesh and mark points on faces in error.
Mesh data needed to do the Finite Volume discretisation.
const Time & time() const
Return the top-level database.
const word & name() const
Return reference to name.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
const pointField & preMotionPoints() const
Pre-motion point positions.
bool hasMotionPoints() const
Has valid preMotionPoints?
Class to store the settings for the polyMeshFilter class.
void writeSettings(Ostream &os) const
Write the settings to a stream.
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.
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.
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.
const labelList nFaces(UPstream::listGatherValues< label >(aMesh.nFaces()))
const labelList nEdges(UPstream::listGatherValues< label >(aMesh.nEdges()))
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.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
int system(const std::string &command, const bool bg=false)
Execute the specified command via the shell.
List< label > labelList
A List of labels.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
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(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
static constexpr const zero Zero
Global zero (0)
List< edge > edgeList
A List of edges.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
List< face > faceList
A List of faces.
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.
Functor wrapper of allow/deny lists of wordRe for filtering.
Unit conversion functions.