Go to the documentation of this file.
33 #include "PatchTools.H"
46 externalDisplacementMeshMover,
71 scalar magV0(
mag(v0));
79 scalar magV1(
mag(v1));
104 if ((pointWallDist[
e[0]].
data() & pointWallDist[
e[1]].
data()) < minCos)
118 <<
" : Calculating distance to Medial Axis ..." <<
endl;
132 coeffDict.
lookup(
"nSmoothSurfaceNormals")
136 word angleKey =
"minMedialAxisAngle";
137 if (!coeffDict.
found(angleKey))
140 angleKey =
"minMedianAxisAngle";
151 const scalar slipFeatureAngle =
153 coeffDict.
found(
"slipFeatureAngle")
161 coeffDict.
lookup(
"nSmoothNormals")
214 nSmoothSurfaceNormals,
229 int dummyTrackData = 0;
237 forAll(meshPoints, patchPointI)
239 label pointI = meshPoints[patchPointI];
244 pointNormals[patchPointI]
260 wallDistCalc.
iterate(nMedialAxisIter);
270 if (nMedialAxisIter > 0)
273 <<
" : Limited walk to " << nMedialAxisIter
274 <<
" steps. Not visited " << nUnvisit
276 <<
" points" <<
endl;
281 <<
"Walking did not visit all points." <<
nl
282 <<
" Did not visit " << nUnvisit
284 <<
" points. This is not necessarily a problem" <<
nl
285 <<
" and might be due to faceZones splitting of part"
286 <<
" of the domain." <<
nl <<
endl;
308 const edge&
e = edges[edgeI];
312 !pointWallDist[
e[0]].valid(dummyTrackData)
313 || !pointWallDist[
e[1]].valid(dummyTrackData)
321 if (!pointMedialDist[pointI].valid(dummyTrackData))
332 pointMedialDist[pointI] = maxInfo.last();
337 else if (
isMaxEdge(pointWallDist, edgeI, minMedialAxisAngleCos))
345 scalar eMag =
mag(eVec);
353 scalar dist0 = (p0-pointWallDist[
e[0]].origin()) & eVec;
354 scalar dist1 = (pointWallDist[
e[1]].origin()-p1) & eVec;
355 scalar
s = 0.5*(dist1+eMag+dist0);
362 else if (
s >= dist0+eMag)
368 medialAxisPt = p0+(
s-dist0)*eVec;
375 if (!pointMedialDist[pointI].valid(dummyTrackData))
386 pointMedialDist[pointI] = maxInfo.last();
409 && !isA<emptyPolyPatch>(pp)
410 && !adaptPatches.
found(patchI)
424 <<
" : Inserting all points on patch " << pp.
name()
429 label pointI = meshPoints[i];
430 if (!pointMedialDist[pointI].valid(dummyTrackData))
441 pointMedialDist[pointI] = maxInfo.last();
453 <<
" : Inserting points on patch " << pp.
name()
454 <<
" if angle to nearest layer patch > "
455 << slipFeatureAngle <<
" degrees." <<
endl;
468 label pointI = meshPoints[i];
472 pointWallDist[pointI].valid(dummyTrackData)
473 && !pointMedialDist[pointI].valid(dummyTrackData)
479 -pointWallDist[pointI].data()
482 if (cosAngle > slipFeatureAngleCos)
496 pointMedialDist[pointI] = maxInfo.last();
524 medialDistCalc.
iterate(2*nMedialAxisIter);
528 forAll(pointMedialDist, pointI)
530 if (pointMedialDist[pointI].valid(dummyTrackData))
534 pointMedialDist[pointI].distSqr()
536 medialVec_[pointI] = pointMedialDist[pointI].origin();
550 if (!pointWallDist[i].valid(dummyTrackData))
556 dispVec_[i] = pointWallDist[i].data();
573 if (!pointWallDist[pointI].valid(dummyTrackData))
579 scalar wDist2 = pointWallDist[pointI].distSqr();
582 if (wDist2 <
sqr(SMALL) && mDist < SMALL)
602 <<
" : Writing medial axis fields:" <<
nl
604 <<
"ratio of medial distance to wall distance : "
606 <<
"distance to nearest medial axis : "
608 <<
"nearest medial axis location : "
610 <<
"normal at nearest wall : "
625 const label patchPointI,
659 label nChangedTotal = 0;
678 if (
mag(patchDisp[i]) < minThickness[i])
680 if (unmarkExtrusion(i, patchDisp, extrudeStatus))
751 nChangedTotal += nChanged;
783 boolList extrudedFaces(pp.size(),
true);
793 extrudedFaces[faceI] =
false;
816 const labelList& eFaces = edgeFaces[edgeI];
822 label faceI = eFaces[i];
823 edgeFaceNormals[edgeI][i] = faceNormals[faceI];
824 edgeFaceExtrude[edgeI][i] = extrudedFaces[faceI];
847 forAll(edgeFaceNormals, edgeI)
849 const List<point>& eFaceNormals = edgeFaceNormals[edgeI];
850 const List<bool>& eFaceExtrude = edgeFaceExtrude[edgeI];
852 if (eFaceNormals.
size() == 2)
864 if (!eFaceExtrude[0] || !eFaceExtrude[1])
866 const vector& n0 = eFaceNormals[0];
867 const vector& n1 = eFaceNormals[1];
869 if ((n0 & n1) < minCos)
871 if (unmarkExtrusion(v0, patchDisp, extrudeStatus))
873 if (isPatchMasterPoint[v0])
878 if (unmarkExtrusion(v1, patchDisp, extrudeStatus))
880 if (isPatchMasterPoint[v1])
902 const scalar minCosLayerTermination,
903 const bool detectExtrusionIsland,
917 Info<< typeName <<
" : Removing isolated regions ..." <<
nl
918 <<
indent <<
"- if partially extruded faces make angle < "
920 if (detectExtrusionIsland)
922 Info<<
indent <<
"- if exclusively surrounded by non-extruded points"
927 Info<<
indent <<
"- if exclusively surrounded by non-extruded faces"
932 label nPointCounter = 0;
938 if (minCosLayerTermination > -1)
940 handleFeatureAngleLayerTerminations
942 minCosLayerTermination,
951 syncPatchDisplacement(minThickness, patchDisp, extrudeStatus);
964 if (detectExtrusionIsland)
979 if (islandPoint[faceI] == -1)
982 islandPoint[faceI] =
f[fp];
984 else if (islandPoint[faceI] != -2)
987 islandPoint[faceI] = -2;
999 forAll(pointFaces, patchPointI)
1008 if (islandPoint[faceI] != patchPointI)
1010 keptPoints[patchPointI] =
true;
1023 boolList extrudedFaces(pp.size(),
true);
1031 extrudedFaces[faceI] =
false;
1039 forAll(keptPoints, patchPointI)
1046 if (extrudedFaces[faceI])
1048 keptPoints[patchPointI] =
true;
1067 forAll(keptPoints, patchPointI)
1069 if (!keptPoints[patchPointI])
1071 if (unmarkExtrusion(patchPointI, patchDisp, extrudeStatus))
1096 if (isPatchMasterEdge[edgeI])
1098 const edge&
e = edges[edgeI];
1105 isolatedPoint[v0] += 1;
1109 isolatedPoint[v1] += 1;
1128 bool failed =
false;
1131 if (isolatedPoint[
f[fp]] > 2)
1137 bool allPointsExtruded =
true;
1144 allPointsExtruded =
false;
1149 if (allPointsExtruded)
1172 <<
" : Number of isolated points extrusion stopped : "<< nPointCounter
1187 adaptPatchIDs_(getFixedValueBCs(pointDisplacement)),
1188 adaptPatchPtr_(getPatch(
mesh(), adaptPatchIDs_)),
1194 pointDisplacement.time().timeName(),
1195 pointDisplacement.db(),
1214 fieldSmoother_(
mesh()),
1220 pointDisplacement.time().timeName(),
1221 pointDisplacement.db(),
1234 pointDisplacement.time().timeName(),
1235 pointDisplacement.db(),
1248 pointDisplacement.time().timeName(),
1249 pointDisplacement.db(),
1262 pointDisplacement.time().timeName(),
1263 pointDisplacement.db(),
1292 Info<< typeName <<
" : Smoothing using Medial Axis ..." <<
endl;
1304 "nSmoothDisplacement",
1309 const scalar maxThicknessToMedialRatio =
readScalar
1311 coeffDict.
lookup(
"maxThicknessToMedialRatio")
1320 "layerTerminationAngle",
1328 coeffDict.
lookup(
"nSmoothThickness")
1341 "detectExtrusionIsland",
1380 forAll(thickness, patchPointI)
1384 thickness[patchPointI] = 0.0;
1388 label numThicknessRatioExclude = 0;
1401 /
"thicknessRatioExcludePoints_"
1407 <<
" : Writing points with too large an extrusion distance to "
1408 << str().name() <<
endl;
1419 /
"thicknessRatioExcludeMedialVec_"
1425 <<
" : Writing medial axis vectors on points with too large"
1426 <<
" an extrusion distance to " << medialVecStr().name() <<
endl;
1429 forAll(meshPoints, patchPointI)
1433 label pointI = meshPoints[patchPointI];
1437 scalar mDist = medialDist_[pointI];
1438 scalar thicknessRatio = thickness[patchPointI]/(mDist+VSMALL);
1443 patchDisp[patchPointI]
1444 / (
mag(patchDisp[patchPointI]) + VSMALL);
1446 mVec /=
mag(mVec)+VSMALL;
1447 thicknessRatio *= (
n&mVec);
1449 if (thicknessRatio > maxThicknessToMedialRatio)
1454 Pout<<
"truncating displacement at "
1456 <<
" from " << thickness[patchPointI]
1460 minThickness[patchPointI]
1461 +thickness[patchPointI]
1463 <<
" medial direction:" << mVec
1464 <<
" extrusion direction:" <<
n
1465 <<
" with thicknessRatio:" << thicknessRatio
1469 thickness[patchPointI] =
1470 0.5*(minThickness[patchPointI]+thickness[patchPointI]);
1472 patchDisp[patchPointI] = thickness[patchPointI]*
n;
1474 if (isPatchMasterPoint[patchPointI])
1476 numThicknessRatioExclude++;
1482 str().write(
linePointRef(pt, pt+patchDisp[patchPointI]));
1484 if (medialVecStr.
valid())
1487 medialVecStr().write
1501 Info<< typeName <<
" : Reducing layer thickness at "
1502 << numThicknessRatioExclude
1503 <<
" nodes where thickness to medial axis distance is large " <<
endl;
1510 minCosLayerTermination,
1511 detectExtrusionIsland,
1523 forAll(thickness, patchPointI)
1527 thickness[patchPointI] = 0.0;
1536 fieldSmoother_.minSmoothField
1538 nSmoothPatchThickness,
1548 int dummyTrackData = 0;
1563 forAll(meshPoints, patchPointI)
1565 label pointI = meshPoints[patchPointI];
1566 wallPoints[patchPointI] = pointI;
1571 thickness[patchPointI]
1586 wallDistCalc.
iterate(nMedialAxisIter);
1591 pointField& displacement = pointDisplacement_;
1593 forAll(displacement, pointI)
1595 if (!pointWallDist[pointI].valid(dummyTrackData))
1606 displacement[pointI] =
1607 -medialRatio_[pointI]
1608 *pointWallDist[pointI].data()
1615 if (nSmoothDisplacement > 0)
1622 medialRatio_[i] > SMALL && medialRatio_[i] < 1-SMALL;
1625 fieldSmoother_.smoothLambdaMuDisplacement
1627 nSmoothDisplacement,
1640 const label nAllowableErrors,
1650 meshMover_.setDisplacementPatchFields();
1652 Info<< typeName <<
" : Moving mesh ..." <<
endl;
1653 scalar oldErrorReduction = -1;
1655 bool meshOk =
false;
1657 for (
label iter = 0; iter < 2*nSnap ; iter++)
1660 <<
" : Iteration " << iter <<
endl;
1664 <<
" : Displacement scaling for error reduction set to 0."
1666 oldErrorReduction = meshMover_.setErrorReduction(0.0);
1671 meshMover_.scaleMesh
1675 meshMover_.paramDict(),
1682 Info<< typeName <<
" : Successfully moved mesh" <<
endl;
1688 if (oldErrorReduction >= 0)
1690 meshMover_.setErrorReduction(oldErrorReduction);
1693 Info<< typeName <<
" : Finished moving mesh ..." <<
endl;
1702 const label nAllowableErrors,
1710 const word minThicknessName =
word(moveDict.
lookup(
"minThicknessName"));
1717 if (minThicknessName ==
"none")
1723 (minThicknessName ==
"none")
1731 pointDisplacement_.internalField(),
1740 forAll(extrudeStatus, pointI)
1742 if (
mag(patchDisp[pointI]) <= minThickness[pointI]+SMALL)
1750 calculateDisplacement(moveDict, minThickness, extrudeStatus, patchDisp);
1767 meshMover_.movePoints();
1770 meshMover_.correct();
virtual const pointField & points() const
Return raw points.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
const labelListList & pointFaces() const
Return point-face addressing.
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
const labelListList & edgeFaces() const
Return edge-face addressing.
A class for handling words, derived from string.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
OFstream which keeps track of vertices.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
#define forAll(list, i)
Loop across all elements in list.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
Wave propagation of information through grid. Every iteration information goes through one layer of e...
label nEdges() const
Return number of edges in patch.
label nTotalPoints() const
Return total number of points in decomposed mesh. Not.
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
labelList meshEdges(const edgeList &allEdges, const labelListList &cellEdges, const labelList &faceCells) const
Return labels of patch edges in the global edge list using.
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
Unit conversion functions.
GeometricBoundaryField & boundaryField()
Return reference to GeometricBoundaryField.
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Ostream & endl(Ostream &os)
Add newline and flush stream.
const edgeList & edges() const
Return mesh edges. Uses calcEdges.
dimensioned< scalar > mag(const dimensioned< Type > &)
void smoothNormals(const label nIter, const PackedBoolList &isMeshMasterPoint, const PackedBoolList &isMeshMasterEdge, const labelList &fixedPoints, pointVectorField &normals) const
Smooth interior normals.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Variant of pointEdgePoint with some transported additional data. Templated on the transported data ty...
Abstract base class for point-mesh patch fields.
Mesh consisting of general polyhedral cells.
pointVectorField & pointDisplacement()
Return reference to the point motion displacement field.
dimensioned< vector > dimensionedVector
Dimensioned vector obtained from generic dimensioned type.
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=*(cellModeller::lookup("hex"));labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells]=cellShape(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< SMALL) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} label minLabel=min(start, end);pointMap[start]=pointMap[end]=minLabel;} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};const label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &oldCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< SLList< face > > pFaces[nBCs]
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Pre-declare SubField and related Field type.
label iterate(const label maxIter)
Iterate until no changes or maxIter reached. Returns actual.
A patch is a list of labels that address the faces in the global face list.
virtual void movePoints(const pointField &)
Update local data for geometry changes.
Virtual base class for mesh movers with externally provided displacement field giving the boundary co...
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & shrink()
Shrink the allocated space to the number of elements used.
label nPoints() const
Return number of points supporting patch faces.
A list of keyword definitions, which are a keyword followed by any number of values (e....
label getUnsetPoints() const
Macros for easy insertion into run-time selection tables.
bool found(const Key &) const
Return true if hashedEntry is found in table.
Mesh representing a set of points created from polyMesh.
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
void smoothPatchNormals(const label nIter, const PackedBoolList &isPatchMasterPoint, const PackedBoolList &isPatchMasterEdge, const indirectPrimitivePatch &adaptPatch, pointField &normals) const
Smooth patch normals.
const double e
Elementary charge.
Ostream & indent(Ostream &os)
Indent stream.
Vector< scalar > vector
A scalar version of the templated Vector.
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))
static PackedBoolList getMasterEdges(const polyMesh &mesh, const labelList &meshEdges)
Determine master edge for subset of edges. If coupled.
Holds information regarding nearest wall point. Used in PointEdgeWave. (so not standard FaceCellWave)...
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
void setSize(const label)
Reset size of List.
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
line< point, const point & > linePointRef
Line using referred points.
static PackedBoolList getMasterPoints(const polyMesh &mesh, const labelList &meshPoints)
Determine master point for subset of points. If coupled.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
bool readScalar(const char *buf, doubleScalar &s)
Read whole of buf as a scalar. Return true if succesful.
prefixOSstream Pout(cout, "Pout")
const Field< PointType > & faceNormals() const
Return face normals for patch.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensionedScalar acos(const dimensionedScalar &ds)
bool valid() const
Return true if the autoPtr valid (ie, the pointer is set).
static const Vector rootMax
const dimensionedScalar e
Elementary charge.
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
label readLabel(Istream &is)
scalar radToDeg(const scalar rad)
Conversion from radians to degrees.
void reset(T *=0)
If object pointer already set, delete object and set to given.
const List< Face > & localFaces() const
Return patch faces addressing into local point list.
virtual bool fixesValue() const
Return true if this patch field fixes a value.
A face is a list of labels corresponding to mesh vertices.
const Type & lookupObject(const word &name) const
Lookup and return the object of the given Type.
void size(const label)
Override size to be inconsistent with allocated storage.
const globalMeshData & globalData() const
Return parallel info.
vector point
Point is a vector.
const labelList & meshPoints() const
Return labelList of mesh points in patch.
Generic GeometricField class.
defineTypeNameAndDebug(combustionModel, 0)
const word & name() const
Return name.
#define WarningInFunction
Report a warning using Foam::Warning.
Database for solution data, solver performance and other reduced data.
dimensioned< scalar > magSqr(const dimensioned< Type > &)
const polyMesh & mesh() const
A list of faces which address into the list of points.
scalar degToRad(const scalar deg)
Conversion from degrees to radians.
dimensionedScalar cos(const dimensionedScalar &ds)