48 void Foam::meshRefinement::markBoundaryFace
56 isBoundaryFace[facei] =
true;
62 isBoundaryEdge[fEdges[fp]] =
true;
65 const face& f = mesh_.
faces()[facei];
69 isBoundaryPoint[f[fp]] =
true;
74 void Foam::meshRefinement::findNearest
77 List<pointIndexHit>& nearestInfo,
101 nearestNormal.setSize(nearestInfo.size());
102 nearestRegion.setSize(nearestInfo.size());
104 forAll(allSurfaces, surfi)
106 DynamicList<pointIndexHit> localHits;
110 if (nearestSurface[i] == surfi)
112 localHits.append(nearestInfo[i]);
119 surfaces_.
geometry()[geomi].getNormal(localHits, localNormals);
122 surfaces_.
geometry()[geomi].getRegion(localHits, localRegion);
127 if (nearestSurface[i] == surfi)
129 nearestNormal[i] = localNormals[localI];
130 nearestRegion[i] = localRegion[localI];
145 autoPtr<indirectPrimitivePatch> ppPtr
159 DynamicList<label> candidateFaces(pp.size()/20);
167 const labelList& eFaces = edgeFaces[edgei];
169 if (eFaces.size() == 2)
171 const label face0 = pp.addressing()[eFaces[0]];
172 const label face1 = pp.addressing()[eFaces[1]];
177 if (cellLevel[cell0] > cellLevel[cell1])
180 const vector& n0 = pp.faceNormals()[eFaces[0]];
181 const vector& n1 = pp.faceNormals()[eFaces[1]];
183 if (
mag(n0 & n1) < 0.1)
185 candidateFaces.append(face0);
188 else if (cellLevel[cell1] > cellLevel[cell0])
191 const vector& n0 = pp.faceNormals()[eFaces[0]];
192 const vector& n1 = pp.faceNormals()[eFaces[1]];
194 if (
mag(n0 & n1) < 0.1)
196 candidateFaces.append(face1);
201 candidateFaces.shrink();
204 <<
" faces on edge-connected cells of differing level." 207 if (debug&meshRefinement::MESH)
209 faceSet fSet(mesh_,
"edgeConnectedFaces", candidateFaces);
211 Pout<<
"Writing " << fSet.size()
212 <<
" with problematic topology to faceSet " 213 << fSet.objectPath() <<
endl;
221 List<pointIndexHit> nearestInfo;
238 Map<label> candidateCells(candidateFaces.size());
240 faceSet perpFaces(mesh_,
"perpendicularFaces", pp.size()/100);
244 const label facei = candidateFaces[i];
253 const scalar angle =
degToRad(perpendicularAngle[region]);
259 perpFaces.insert(facei);
260 candidateCells.insert
263 globalToPatch[region]
269 if (debug&meshRefinement::MESH)
272 Pout<<
"Writing " << perpFaces.size()
273 <<
" faces that are perpendicular to the surface to set " 274 << perpFaces.objectPath() <<
endl;
277 return candidateCells;
281 bool Foam::meshRefinement::isCollapsedFace
285 const scalar minFaceArea,
286 const scalar maxNonOrtho,
291 const scalar severeNonorthogonalityThreshold =
294 const vector s = mesh_.
faces()[facei].area(points);
295 const scalar magS =
mag(s);
298 if (magS < minFaceArea)
311 const scalar dDotS = (d &
s)/(
mag(d)*magS + vSmall);
313 if (dDotS < severeNonorthogonalityThreshold)
330 const scalar dDotS = (d &
s)/(
mag(d)*magS + vSmall);
332 if (dDotS < severeNonorthogonalityThreshold)
351 bool Foam::meshRefinement::isCollapsedCell
354 const scalar volFraction,
358 const scalar vol = mesh_.
cells()[celli].mag(points, mesh_.
faces());
380 if (adaptPatchIDs.size())
389 const polyPatch& pp = patches[adaptPatchIDs[i]];
394 List<topoDistanceData> cellData(mesh_.
nCells());
395 List<topoDistanceData> faceData(mesh_.
nFaces());
399 List<topoDistanceData> patchData(nFaces);
403 const label patchi = adaptPatchIDs[i];
404 const polyPatch& pp = patches[
patchi];
408 patchFaces[nFaces] = pp.start()+i;
409 patchData[nFaces] = topoDistanceData(patchi, 0);
415 FaceCellWave<topoDistanceData> deltaCalc
427 bool haveWarned =
false;
430 if (!faceData[facei].valid(deltaCalc.data()))
435 <<
"Did not visit some faces, e.g. face " << facei
437 <<
"Assigning these cells to patch " 445 nearestAdaptPatch[facei] = faceData[facei].data();
452 nearestAdaptPatch.setSize(mesh_.
nFaces(), 0);
455 return nearestAdaptPatch;
461 const dictionary& motionDict,
462 const bool removeEdgeConnectedCells,
484 const polyPatch& pp = patches[adaptPatchIDs[i]];
486 label facei = pp.start();
504 const labelList nearestAdaptPatch(nearestPatch(adaptPatchIDs));
514 calcNeighbourData(neiLevel, neiCc);
518 label nBaffleFaces = 0;
522 label nPrevented = 0;
524 if (removeEdgeConnectedCells &&
max(perpendicularAngle) >= 0)
526 Info<<
"markFacesOnProblemCells :" 527 <<
" Checking for edge-connected cells of highly differing sizes." 532 Map<label> problemCells
534 findEdgeConnectedProblemCells
544 const cell& cFaces = mesh_.
cells()[iter.key()];
548 const label facei = cFaces[i];
552 facePatch[facei] = nearestAdaptPatch[facei];
566 Info<<
"markFacesOnProblemCells : Marked " 568 <<
" additional internal faces to be converted into baffles" 571 <<
" cells edge-connected to lower level cells." <<
endl;
573 if (debug&meshRefinement::MESH)
575 cellSet problemCellSet(mesh_,
"problemCells", problemCells.toc());
576 problemCellSet.instance() =
timeName();
577 Pout<<
"Writing " << problemCellSet.size()
578 <<
" cells that are edge connected to coarser cell to set " 579 << problemCellSet.objectPath() <<
endl;
580 problemCellSet.
write();
612 const scalar volFraction =
613 motionDict.lookupOrDefault<scalar>(
"minVolCollapseRatio", -1);
615 const bool checkCollapse = (volFraction > 0);
617 scalar maxNonOrtho = -1;
625 minArea = motionDict.lookup<scalar>(
"minArea");
626 maxNonOrtho = motionDict.lookup<scalar>(
"maxNonOrtho");
628 Info<<
"markFacesOnProblemCells :" 629 <<
" Deleting all-anchor surface cells only if" 630 <<
" snapping them violates mesh quality constraints:" <<
nl 631 <<
" snapped/original cell volume < " << volFraction <<
nl 632 <<
" face area < " << minArea <<
nl 633 <<
" non-orthogonality > " << maxNonOrtho <<
nl 637 autoPtr<indirectPrimitivePatch> ppPtr
646 const pointField& localPoints = pp.localPoints();
647 const labelList& meshPoints = pp.meshPoints();
649 List<pointIndexHit> hitinfo;
661 newPoints = mesh_.
points();
665 if (hitinfo[i].hit())
667 newPoints[meshPoints[i]] = hitinfo[i].hitPoint();
671 if (debug&meshRefinement::MESH)
673 const_cast<Time&
>(mesh_.
time())++;
702 PackedBoolList hasSevenBoundaryAnchorPoints(mesh_.
nCells());
707 DynamicList<label> dynFEdges;
708 DynamicList<label> dynCPoints;
716 label nBoundaryAnchors = 0;
717 label nNonAnchorBoundary = 0;
718 label nonBoundaryAnchor = -1;
722 const label pointi = cPoints[i];
724 if (pointLevel[pointi] <= cellLevel[celli])
727 if (isBoundaryPoint[pointi])
734 nonBoundaryAnchor = pointi;
737 else if (isBoundaryPoint[pointi])
739 nNonAnchorBoundary++;
743 if (nBoundaryAnchors == 8)
745 const cell& cFaces = mesh_.
cells()[celli];
752 if (isBoundaryFace[cFaces[cFacei]])
768 && !isCollapsedCell(newPoints, volFraction, celli)
785 const label facei = cFaces[cf];
789 facePatch[facei] == -1
793 facePatch[facei] = nearestAdaptPatch[facei];
809 else if (nBoundaryAnchors == 7)
812 hasSevenBoundaryAnchorPoints.set(celli, 1u);
813 nonBoundaryAnchors.insert(nonBoundaryAnchor);
822 DynamicList<label> dynPCells;
826 label pointi = iter.key();
835 if (hasSevenBoundaryAnchorPoints.get(pCells[i]) == 1u)
846 label celli = pCells[i];
848 if (hasSevenBoundaryAnchorPoints.get(celli) == 1u)
853 && !isCollapsedCell(newPoints, volFraction, celli)
868 const cell& cFaces = mesh_.
cells()[celli];
872 const label facei = cFaces[cf];
876 facePatch[facei] == -1
880 facePatch[facei] = nearestAdaptPatch[facei];
930 if (facePatch[facei] == -1)
933 label nFaceBoundaryEdges = 0;
937 if (isBoundaryEdge[fEdges[fe]])
939 nFaceBoundaryEdges++;
943 if (nFaceBoundaryEdges == fEdges.size())
967 facePatch[facei] = nearestAdaptPatch[facei];
979 const polyPatch& pp = patches[
patchi];
983 label facei = pp.start();
987 if (facePatch[facei] == -1)
990 label nFaceBoundaryEdges = 0;
994 if (isBoundaryEdge[fEdges[fe]])
996 nFaceBoundaryEdges++;
1000 if (nFaceBoundaryEdges == fEdges.size())
1024 facePatch[facei] = nearestAdaptPatch[facei];
1025 if (isMasterFace[facei])
1054 Info<<
"markFacesOnProblemCells : marked " 1056 <<
" additional internal faces to be converted into baffles." 1061 Info<<
"markFacesOnProblemCells : prevented " 1063 <<
" internal faces from getting converted into baffles." 1073 Foam::labelList Foam::meshRefinement::markFacesOnProblemCellsGeometric
1075 const snapParameters& snapParams,
1076 const dictionary& motionDict
1086 autoPtr<indirectPrimitivePatch> ppPtr
1104 Info<<
"Constructing mesh displacer ..." <<
endl;
1105 Info<<
"Using mesh parameters " << motionDict <<
nl <<
endl;
1109 motionSmoother meshMover
1120 Info<<
"Checking initial mesh ..." <<
endl;
1129 Info<<
"Detected " << nInitErrors <<
" illegal faces" 1130 <<
" (concave, zero area or negative cell pyramid volume)" 1134 Info<<
"Checked initial mesh in = " 1161 const labelList& meshPoints = pp.meshPoints();
1166 newPoints[meshPoints[i]] += disp[i];
1173 minMagSqrEqOp<point>(),
1174 vector(great, great, great)
1188 label nBaffleFaces = 0;
1191 faceSet wrongFaces(mesh_,
"wrongFaces", 100);
1199 label nWrongFaces = 0;
1230 scalar minArea(motionDict.lookup<scalar>(
"minArea"));
1231 if (minArea > -small)
1249 Info<<
" faces with area < " 1250 <<
setw(5) << minArea
1252 << nNewWrongFaces-nWrongFaces <<
endl;
1254 nWrongFaces = nNewWrongFaces;
1257 scalar minDet(motionDict.lookup<scalar>(
"minDeterminant"));
1276 Info<<
" faces on cells with determinant < " 1277 <<
setw(5) << minDet <<
" : " 1278 << nNewWrongFaces-nWrongFaces <<
endl;
1280 nWrongFaces = nNewWrongFaces;
1291 facePatch[iter.key()] = nearestAdaptPatch[iter.key()];
1307 Info<<
"markFacesOnProblemCellsGeometric : marked " 1309 <<
" additional internal and coupled faces" 1310 <<
" to be converted into baffles." <<
endl;
static bool checkMesh(const bool report, const polyMesh &mesh, const dictionary &dict, labelHashSet &wrongFaces)
Check mesh with mesh settings in dict. Collects incorrect faces.
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
List< labelList > labelListList
A List of labelList.
#define forAll(list, i)
Loop across all elements in list.
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
virtual Ostream & write(const char)=0
Write character.
FvWallInfoData< WallInfo, label > label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
const labelList & surfaces() const
bool checkFaceArea(const bool report, const scalar minArea, const polyMesh &, const vectorField &faceAreas, const labelList &checkFaces, labelHashSet *setPtr)
Check for small faces.
const labelIOList & pointLevel() const
const labelListList & faceEdges() const
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
label nInternalFaces() const
virtual const labelList & faceNeighbour() const
Return face neighbour.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Unit conversion functions.
void size(const label)
Override size to be inconsistent with allocated storage.
Ostream & endl(Ostream &os)
Add newline and flush stream.
label nTotalCells() const
Return total number of cells in decomposed mesh.
static writeType writeLevel()
Get/set write level.
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
const cellList & cells() const
Vector< scalar > vector
A scalar version of the templated Vector.
const Time & time() const
Return the top-level database.
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
Foam::indirectPrimitivePatch.
void findNearest(const labelList &surfacesToTest, const pointField &samples, const scalarField &nearestDistSqr, labelList &surfaces, List< pointIndexHit > &) const
Find nearest point on surfaces.
scalar degToRad(const scalar deg)
Conversion from degrees to radians.
virtual const pointField & points() const
Return raw points.
List< bool > boolList
Bool container classes.
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
const searchableSurfaces & geometry() const
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
vectorField pointField
pointField is a vectorField.
dimensionedScalar cos(const dimensionedScalar &ds)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
double cpuTimeIncrement() const
Return CPU time (in seconds) since last call to cpuTimeIncrement()
PolyMesh checking routines. Checks various criteria for a mesh and supplied geometry, with the mesh only used for topology. Coupled patch aware (i.e., coupled faces are treated as internal).
virtual const labelList & faceOwner() const
Return face owner.
const globalMeshData & globalData() const
Return parallel info.
List< label > labelList
A List of labels.
static void preSmoothPatch(const meshRefinement &meshRefiner, const snapParameters &snapParams, const label nInitErrors, const List< labelPair > &baffles, motionSmoother &)
Smooth the mesh (patch and internal) to increase visibility.
virtual const faceList & faces() const
Return raw faces.
const PtrList< surfaceZonesInfo > & surfZones() const
const vectorField & cellCentres() const
static labelList getUnnamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of unnamed surfaces (surfaces without faceZoneName)
const labelListList & pointCells() const
word timeName() const
Replacement for Time::timeName() : return oldInstance (if.
static scalarField calcSnapDistance(const fvMesh &mesh, const snapParameters &snapParams, const indirectPrimitivePatch &)
Calculate edge length per patch point.
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
dimensionedScalar sin(const dimensionedScalar &ds)
Istream and Ostream manipulators taking arguments.
label globalRegion(const label surfi, const label regioni) const
From surface and region on surface to global region.
labelList meshedPatches() const
Get patchIDs for patches added in addMeshedPatch.
static pointMesh & New(polyMesh &mesh)
static autoPtr< indirectPrimitivePatch > makePatch(const polyMesh &, const labelList &)
Create patch from set of patches.
virtual tmp< scalarField > movePoints(const pointField &)
Move points, returns volumes swept by faces in motion.
const vectorField & faceCentres() const
void setSize(const label)
Reset size of List.
bool checkCellDeterminant(const bool report, const scalar minDet, const polyMesh &, const vectorField &faceAreas, const labelList &checkFaces, labelHashSet *setPtr)
Check the area of internal faces v.s. boundary faces.
vector point
Point is a vector.
#define WarningInFunction
Report a warning using Foam::Warning.
prefixOSstream Pout(cout, "Pout")
const vectorField & faceAreas() const
dimensioned< scalar > mag(const dimensioned< Type > &)
Field< vector > vectorField
Specialisation of Field<T> for vector.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Omanip< int > setw(const int i)
bool write() const
Write mesh and all data.
static tmp< pointVectorField > makeDisplacementField(const pointMesh &pMesh, const labelList &adaptPatchIDs)
Helper function to make a pointVectorField with correct.
fileName path() const
Return path.
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
const labelIOList & cellLevel() const
const labelListList & cellPoints() const
const scalarField & cellVolumes() const
A HashTable to objects of type <T> with a label key.
static vectorField calcNearestSurface(const meshRefinement &meshRefiner, const scalarField &snapDist, const indirectPrimitivePatch &, pointField &nearestPoint, vectorField &nearestNormal)
Per patch point calculate point on nearest surface. Set as.