47 void Foam::meshRefinement::markBoundaryFace
55 isBoundaryFace[facei] =
true;
61 isBoundaryEdge[fEdges[fp]] =
true;
64 const face&
f = mesh_.
faces()[facei];
68 isBoundaryPoint[
f[fp]] =
true;
73 void Foam::meshRefinement::findNearest
76 List<pointIndexHit>& nearestInfo,
85 fc[i] = mesh_.faceCentres()[meshFaces[i]];
100 nearestNormal.setSize(nearestInfo.size());
101 nearestRegion.setSize(nearestInfo.size());
103 forAll(allSurfaces, surfi)
105 DynamicList<pointIndexHit> localHits;
109 if (nearestSurface[i] == surfi)
111 localHits.append(nearestInfo[i]);
115 const label geomi = surfaces_.surfaces()[surfi];
118 surfaces_.geometry()[geomi].getNormal(localHits, localNormals);
121 surfaces_.geometry()[geomi].getRegion(localHits, localRegion);
126 if (nearestSurface[i] == surfi)
128 nearestNormal[i] = localNormals[localI];
129 nearestRegion[i] = localRegion[localI];
144 autoPtr<indirectPrimitivePatch> ppPtr
158 DynamicList<label> candidateFaces(pp.size()/20);
162 const labelList& cellLevel = meshCutter_.cellLevel();
166 const labelList& eFaces = edgeFaces[edgei];
168 if (eFaces.size() == 2)
170 const label face0 = pp.addressing()[eFaces[0]];
171 const label face1 = pp.addressing()[eFaces[1]];
173 const label cell0 = mesh_.faceOwner()[face0];
174 const label cell1 = mesh_.faceOwner()[face1];
176 if (cellLevel[cell0] > cellLevel[cell1])
179 const vector& n0 = pp.faceNormals()[eFaces[0]];
180 const vector& n1 = pp.faceNormals()[eFaces[1]];
182 if (
mag(n0 & n1) < 0.1)
184 candidateFaces.append(face0);
187 else if (cellLevel[cell1] > cellLevel[cell0])
190 const vector& n0 = pp.faceNormals()[eFaces[0]];
191 const vector& n1 = pp.faceNormals()[eFaces[1]];
193 if (
mag(n0 & n1) < 0.1)
195 candidateFaces.append(face1);
200 candidateFaces.shrink();
203 <<
" faces on edge-connected cells of differing level."
208 faceSet fSet(mesh_,
"edgeConnectedFaces", candidateFaces);
209 fSet.instance() =
name();
210 Pout<<
"Writing " << fSet.size()
211 <<
" with problematic topology to faceSet "
212 << fSet.objectPath() <<
endl;
220 List<pointIndexHit> nearestInfo;
237 Map<label> candidateCells(candidateFaces.size());
239 faceSet perpFaces(mesh_,
"perpendicularFaces", pp.size()/100);
243 const label facei = candidateFaces[i];
244 const vector n = mesh_.faceAreas()[facei]/
mag(mesh_.faceAreas()[facei]);
246 const label region = surfaces_.globalRegion
252 const scalar angle = perpendicularAngle[region];
258 perpFaces.insert(facei);
259 candidateCells.insert
261 mesh_.faceOwner()[facei],
262 globalToPatch[region]
270 perpFaces.instance() =
name();
271 Pout<<
"Writing " << perpFaces.size()
272 <<
" faces that are perpendicular to the surface to set "
273 << perpFaces.objectPath() <<
endl;
276 return candidateCells;
280 bool Foam::meshRefinement::isCollapsedFace
284 const scalar minFaceArea,
285 const scalar maxNonOrtho,
290 const scalar severeNonorthogonalityThreshold =
::cos(maxNonOrtho);
293 const scalar magS =
mag(
s);
296 if (magS < minFaceArea)
302 const point& ownCc = mesh_.cellCentres()[mesh_.faceOwner()[facei]];
304 if (mesh_.isInternalFace(facei))
306 const label nei = mesh_.faceNeighbour()[facei];
307 const vector d = mesh_.cellCentres()[nei] - ownCc;
309 const scalar dDotS = (d &
s)/(
mag(d)*magS + vSmall);
311 if (dDotS < severeNonorthogonalityThreshold)
322 const label patchi = mesh_.boundaryMesh().whichPatch(facei);
324 if (mesh_.boundaryMesh()[
patchi].coupled())
326 const vector d = neiCc[facei-mesh_.nInternalFaces()] - ownCc;
328 const scalar dDotS = (d &
s)/(
mag(d)*magS + vSmall);
330 if (dDotS < severeNonorthogonalityThreshold)
349 bool Foam::meshRefinement::isCollapsedCell
352 const scalar volFraction,
356 const scalar vol = mesh_.cells()[celli].mag(
points, mesh_.faces());
358 if (vol/mesh_.cellVolumes()[celli] < volFraction)
374 const polyBoundaryMesh&
patches = mesh_.boundaryMesh();
378 if (adaptPatchIDs.size())
380 nearestAdaptPatch.
setSize(mesh_.nFaces(), adaptPatchIDs[0]);
387 const polyPatch& pp =
patches[adaptPatchIDs[i]];
392 List<topoDistanceData> cellData(mesh_.nCells());
393 List<topoDistanceData> faceData(mesh_.nFaces());
397 List<topoDistanceData> patchData(nFaces);
406 patchFaces[nFaces] = pp.start()+i;
407 patchData[nFaces] = topoDistanceData(
patchi, 0);
413 FaceCellWave<topoDistanceData> deltaCalc
420 mesh_.globalData().nTotalCells()+1
425 bool haveWarned =
false;
428 if (!faceData[facei].
valid(deltaCalc.data()))
433 <<
"Did not visit some faces, e.g. face " << facei
434 <<
" at " << mesh_.faceCentres()[facei] <<
endl
435 <<
"Assigning these cells to patch "
443 nearestAdaptPatch[facei] = faceData[facei].data();
450 nearestAdaptPatch.setSize(mesh_.nFaces(), 0);
453 return nearestAdaptPatch;
459 const dictionary& motionDict,
460 const bool removeEdgeConnectedCells,
465 const labelList& cellLevel = meshCutter_.cellLevel();
466 const labelList& pointLevel = meshCutter_.pointLevel();
467 const polyBoundaryMesh&
patches = mesh_.boundaryMesh();
472 boolList isBoundaryPoint(mesh_.nPoints(),
false);
473 boolList isBoundaryEdge(mesh_.nEdges(),
false);
474 boolList isBoundaryFace(mesh_.nFaces(),
false);
478 labelList adaptPatchIDs(meshedPatches());
482 const polyPatch& pp =
patches[adaptPatchIDs[i]];
484 label facei = pp.start();
502 const labelList nearestAdaptPatch(nearestPatch(adaptPatchIDs));
510 labelList neiLevel(mesh_.nFaces()-mesh_.nInternalFaces());
511 pointField neiCc(mesh_.nFaces()-mesh_.nInternalFaces());
512 calcNeighbourData(neiLevel, neiCc);
516 label nBaffleFaces = 0;
520 label nPrevented = 0;
522 if (removeEdgeConnectedCells &&
max(perpendicularAngle) >= 0)
524 Info<<
"markFacesOnProblemCells :"
525 <<
" Checking for edge-connected cells of highly differing sizes."
530 Map<label> problemCells
532 findEdgeConnectedProblemCells
542 const cell& cFaces = mesh_.cells()[iter.key()];
546 const label facei = cFaces[i];
548 if (facePatch[facei] == -1 && mesh_.isInternalFace(facei))
550 facePatch[facei] = nearestAdaptPatch[facei];
564 Info<<
"markFacesOnProblemCells : Marked "
566 <<
" additional internal faces to be converted into baffles"
569 <<
" cells edge-connected to lower level cells." <<
endl;
573 cellSet problemCellSet(mesh_,
"problemCells", problemCells.toc());
574 problemCellSet.instance() =
name();
575 Pout<<
"Writing " << problemCellSet.size()
576 <<
" cells that are edge connected to coarser cell to set "
577 << problemCellSet.objectPath() <<
endl;
578 problemCellSet.
write();
610 const scalar volFraction =
611 motionDict.lookupOrDefault<scalar>(
"minVolCollapseRatio", -1);
613 const bool checkCollapse = (volFraction > 0);
615 scalar maxNonOrtho = -1;
623 minArea = motionDict.lookup<scalar>(
"minArea");
624 maxNonOrtho = motionDict.lookup<scalar>(
"maxNonOrtho",
unitDegrees);
626 Info<<
"markFacesOnProblemCells :"
627 <<
" Deleting all-anchor surface cells only if"
628 <<
" snapping them violates mesh quality constraints:" <<
nl
629 <<
" snapped/original cell volume < " << volFraction <<
nl
630 <<
" face area < " << minArea <<
nl
631 <<
" non-orthogonality > " <<
radToDeg(maxNonOrtho)
635 autoPtr<indirectPrimitivePatch> ppPtr
644 const pointField& localPoints = pp.localPoints();
645 const labelList& meshPoints = pp.meshPoints();
647 List<pointIndexHit> hitinfo;
649 surfaces_.findNearest
659 newPoints = mesh_.points();
663 if (hitinfo[i].hit())
665 newPoints[meshPoints[i]] = hitinfo[i].hitPoint();
671 const_cast<Time&
>(mesh_.time())++;
673 mesh_.setPoints(newPoints);
674 Pout<<
"Writing newPoints mesh to time " <<
name()
679 writeType(writeLevel() | WRITEMESH),
680 mesh_.time().path()/
"newPoints"
682 mesh_.setPoints(oldPoints);
700 PackedBoolList hasSevenBoundaryAnchorPoints(mesh_.nCells());
705 DynamicList<label> dynFEdges;
706 DynamicList<label> dynCPoints;
710 const labelList& cPoints = mesh_.cellPoints(celli, dynCPoints);
714 label nBoundaryAnchors = 0;
715 label nonBoundaryAnchor = -1;
719 const label pointi = cPoints[i];
721 if (pointLevel[pointi] <= cellLevel[celli])
724 if (isBoundaryPoint[pointi])
731 nonBoundaryAnchor = pointi;
736 if (nBoundaryAnchors == 8)
738 const cell& cFaces = mesh_.cells()[celli];
743 && !isCollapsedCell(newPoints, volFraction, celli)
761 const label facei = cFaces[cf];
765 facePatch[facei] == -1
766 && mesh_.isInternalFace(facei)
769 facePatch[facei] = nearestAdaptPatch[facei];
784 else if (nBoundaryAnchors == 7)
787 hasSevenBoundaryAnchorPoints.set(celli, 1u);
788 nonBoundaryAnchors.insert(nonBoundaryAnchor);
797 DynamicList<label> dynPCells;
801 label pointi = iter.key();
803 const labelList& pCells = mesh_.pointCells(pointi, dynPCells);
810 if (hasSevenBoundaryAnchorPoints.get(pCells[i]) == 1u)
821 label celli = pCells[i];
823 if (hasSevenBoundaryAnchorPoints.get(celli) == 1u)
828 && !isCollapsedCell(newPoints, volFraction, celli)
843 const cell& cFaces = mesh_.cells()[celli];
847 const label facei = cFaces[cf];
851 facePatch[facei] == -1
852 && mesh_.isInternalFace(facei)
855 facePatch[facei] = nearestAdaptPatch[facei];
903 for (
label facei = 0; facei < mesh_.nInternalFaces(); facei++)
905 if (facePatch[facei] == -1)
907 const labelList& fEdges = mesh_.faceEdges(facei, dynFEdges);
908 label nFaceBoundaryEdges = 0;
912 if (isBoundaryEdge[fEdges[fe]])
914 nFaceBoundaryEdges++;
918 if (nFaceBoundaryEdges == fEdges.size())
942 facePatch[facei] = nearestAdaptPatch[facei];
958 label facei = pp.start();
962 if (facePatch[facei] == -1)
964 const labelList& fEdges = mesh_.faceEdges(facei, dynFEdges);
965 label nFaceBoundaryEdges = 0;
969 if (isBoundaryEdge[fEdges[fe]])
971 nFaceBoundaryEdges++;
975 if (nFaceBoundaryEdges == fEdges.size())
999 facePatch[facei] = nearestAdaptPatch[facei];
1000 if (isMasterFace[facei])
1029 Info<<
"markFacesOnProblemCells : marked "
1031 <<
" additional internal faces to be converted into baffles."
1036 Info<<
"markFacesOnProblemCells : prevented "
1038 <<
" internal faces from getting converted into baffles."
1048 Foam::labelList Foam::meshRefinement::markFacesOnProblemCellsGeometric
1050 const snapParameters& snapParams,
1051 const dictionary& motionDict
1058 labelList adaptPatchIDs(meshedPatches());
1061 autoPtr<indirectPrimitivePatch> ppPtr
1079 Info<<
"Constructing mesh displacer ..." <<
endl;
1080 Info<<
"Using mesh parameters " << motionDict <<
nl <<
endl;
1084 motionSmoother meshMover
1095 Info<<
"Checking initial mesh ..." <<
endl;
1104 Info<<
"Detected " << nInitErrors <<
" illegal faces"
1105 <<
" (concave, zero area or negative cell pyramid volume)"
1109 Info<<
"Checked initial mesh in = "
1110 << mesh_.time().cpuTimeIncrement() <<
" s\n" <<
nl <<
endl;
1136 const labelList& meshPoints = pp.meshPoints();
1141 newPoints[meshPoints[i]] += disp[i];
1148 minMagSqrEqOp<point>(),
1149 vector(great, great, great)
1152 mesh_.setPoints(newPoints);
1157 const labelList nearestAdaptPatch(nearestPatch(meshedPatches()));
1161 labelList facePatch(mesh_.nFaces(), -1);
1163 label nBaffleFaces = 0;
1166 faceSet wrongFaces(mesh_,
"wrongFaces", 100);
1174 label nWrongFaces = 0;
1205 scalar minArea(motionDict.lookup<scalar>(
"minArea"));
1206 if (minArea > -small)
1224 Info<<
" faces with area < "
1225 <<
setw(5) << minArea
1227 << nNewWrongFaces-nWrongFaces <<
endl;
1229 nWrongFaces = nNewWrongFaces;
1232 scalar minDet(motionDict.lookup<scalar>(
"minDeterminant"));
1251 Info<<
" faces on cells with determinant < "
1252 <<
setw(5) << minDet <<
" : "
1253 << nNewWrongFaces-nWrongFaces <<
endl;
1255 nWrongFaces = nNewWrongFaces;
1262 label patchi = mesh_.boundaryMesh().whichPatch(iter.key());
1264 if (
patchi == -1 || mesh_.boundaryMesh()[
patchi].coupled())
1266 facePatch[iter.key()] = nearestAdaptPatch[iter.key()];
1279 mesh_.setPoints(oldPoints);
1282 Info<<
"markFacesOnProblemCellsGeometric : marked "
1284 <<
" additional internal and coupled faces"
1285 <<
" to be converted into baffles." <<
endl;
Istream and Ostream manipulators taking arguments.
#define forAll(list, i)
Loop across all elements in list.
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
static pointMesh & New(const word &name, const polyMesh &mesh)
Construct and return the named DemandDrivenMeshObject.
void setSize(const label)
Reset size of List.
A HashTable to objects of type <T> with a label key.
virtual Ostream & write(const char)=0
Write character.
label size() const
Return the number of elements in the UPtrList.
static tmp< pointVectorField > makeDisplacementField(const pointMesh &pMesh, const labelList &adaptPatchIDs)
Helper function to make a pointVectorField with correct.
static autoPtr< indirectPrimitivePatch > makePatch(const polyMesh &, const labelList &)
Create patch from set of patches.
virtual const faceList & faces() const
Return raw faces.
const labelListList & faceEdges() const
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.
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.
static scalarField calcSnapDistance(const fvMesh &mesh, const snapParameters &snapParams, const indirectPrimitivePatch &)
Calculate edge length per patch point.
static labelList getUnnamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of unnamed surfaces (surfaces without faceZoneName)
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.name(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
const fvPatchList & patches
Functions for checking mesh topology and geometry.
#define WarningInFunction
Report a warning using Foam::Warning.
bool valid(const PtrList< ModelType > &l)
bool checkMesh(const bool report, const polyMesh &mesh, const dictionary &dict, const labelList &checkFaces, const List< labelPair > &baffles, labelHashSet &wrongFaces)
Check (subset of mesh including baffles) with mesh settings in dict.
bool checkFaceArea(const bool report, const scalar minArea, const polyMesh &, const vectorField &faceAreas, const labelList &checkFaces, labelHashSet *setPtr)
Check for small faces.
bool checkCellDeterminant(const polyMesh &mesh, const bool report, labelHashSet *setPtr)
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
scalar radToDeg(const scalar rad)
Convert radians to degrees.
List< label > labelList
A List of labels.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Ostream & endl(Ostream &os)
Add newline and flush stream.
word name(const bool)
Return a word representation of a bool.
Omanip< int > setw(const int i)
dimensionedScalar sin(const dimensionedScalar &ds)
vectorField pointField
pointField is a vectorField.
List< bool > boolList
Bool container classes.
vector point
Point is a vector.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Vector< scalar > vector
A scalar version of the templated Vector.
List< labelList > labelListList
A List of labelList.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
dimensioned< scalar > mag(const dimensioned< Type > &)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
Field< vector > vectorField
Specialisation of Field<T> for vector.
prefixOSstream Pout(cout, "Pout")
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
Foam::indirectPrimitivePatch.
dimensionedScalar cos(const dimensionedScalar &ds)
const unitConversion unitDegrees