62 const bitSet& isMasterPoint,
71 Field<weightedPosition> wps
80 weightedPosition& wp = wps[verti];
81 for (
const label edgei : pointEdges[verti])
83 const label otherVerti = edges[edgei].otherVertex(verti);
85 if (isMasterPoint[meshPoints[otherVerti]])
88 wp.second() += localPoints[otherVerti];
95 tmp<pointField> tavg(
new pointField(wps.size()));
100 const weightedPosition& wp = wps[verti];
102 if (
mag(wp.first()) < VSMALL)
109 avg[verti] = wp.second()/wp.first();
118 Foam::snappySnapDriver::smoothLambdaMuPatchDisplacement
120 const polyMesh&
mesh,
122 const List<labelPair>& baffles
129 const label
iters = 90;
130 const scalar
lambda = 0.33;
131 const scalar
mu = 0.34;
133 for (label iter = 0; iter <
iters; iter++)
137 (1 -
lambda)*newLocalPoints
142 (1 +
mu)*newLocalPoints
143 -
mu*avg(
mesh, isMasterPoint,
pp, newLocalPoints);
150 Foam::snappySnapDriver::wantedThickness
153 const scalar cellSizeFraction
156 fvMesh&
mesh = meshRefiner_.mesh();
158 const labelList& cellLevel = meshRefiner_.meshCutter().cellLevel();
162 const scalar edge0Len =
163 meshRefiner_.meshCutter().level0EdgeLength();
173 label ownLevel = cellLevel[owner[
pp.addressing()[i]]];
179 maxPointLevel[
f[fp]] =
max(maxPointLevel[
f[fp]], ownLevel);
194 const scalar edgeLen = edge0Len/(1<<maxPointLevel[pointi]);
195 thickness[pointi] = cellSizeFraction*edgeLen;
404 Foam::snappySnapDriver::makeMotionSolver
406 const pointMesh& pMesh,
407 const dictionary& snapDict,
412 fvMesh&
mesh = meshRefiner_.mesh();
414 tmp<pointVectorField> tallDisp
425 tallDisp.ref().checkOut();
427 autoPtr<displacementMotionSolver> motionPtr
431 snapDict.get<word>(
"solver"),
438 pMesh.thisDb().time().constant(),
452 pMesh.thisDb().time().constant(),
467 void Foam::snappySnapDriver::setDisplacement
476 const pointMesh& pMesh =
fld.mesh();
485 || (meshPoints.size() != patchDisp.size())
492 <<
" fld.size():" <<
fld.size()
493 <<
" patchDisp.size():" << patchDisp.size()
494 <<
" meshPoints.size():" << meshPoints.size()
495 <<
" mesh.nPoints():" << pMesh.size()
505 forAll(meshPoints, patchPointi)
507 const label meshPointi = meshPoints[patchPointi];
509 meshDisp[meshPointi] =
510 patchDisp[patchPointi]+
points[meshPointi]-
points0[meshPointi];
515 for (
const label patchi : adaptPatchIDs)
517 bfld[patchi] ==
pointField(meshDisp, bfld[patchi].
patch().meshPoints());
524 pcs.constrainDisplacement(
fld,
true);
533 addPatchCellLayer& addLayer
536 fvMesh&
mesh = meshRefiner_.mesh();
567 forAll(edgeGlobalFaces, edgei)
569 if (edgeGlobalFaces[edgei].size() > 2)
574 nPointLayers[
e[0]] = 0;
575 nPointLayers[
e[1]] = 0;
585 else if (edgeGlobalFaces[edgei].size() == 0)
607 const UIndirectList<label> pLayers(nPointLayers,
f);
608 if (!pLayers.found(label(1)))
610 nFaceLayers[facei] = 0;
639 polyTopoChange meshMod(
mesh);
645 addLayer.setRefinement
669 autoPtr<mapPolyMesh> mapPtr = meshMod.changeMesh(
mesh,
false);
670 mapPolyMesh& map = *mapPtr;
676 if (map.hasMotionPoints())
700 for (
const labelList& faceToCells : addedCells)
702 for (
const label celli : faceToCells)
707 meshRefiner_.updateMesh(map, isChangedFace.toc());
712 Info<<
"Writing mesh-with-layer to time " 713 << meshRefiner_.timeName() <<
endl;
722 meshRefiner_.timeName()
729 void Foam::snappySnapDriver::doSnapBufferLayers
731 const dictionary& snapDict,
732 const dictionary& motionDict,
734 const scalar featureCos,
735 const scalar planarAngle,
736 const snapParameters& snapParams
740 fvMesh&
mesh = meshRefiner_.mesh();
743 <<
"Morphing phase" <<
nl 744 <<
"--------------" <<
nl 790 meshRefiner_.getZones
792 List<surfaceZonesInfo::faceZoneType>
804 List<labelPair> baffles;
806 meshRefiner_.createZoneBaffles
816 meshRefiner_.dupNonManifoldBoundaryPoints();
822 meshRefiner_.subsetBaffles
831 bool doFeatures =
true;
833 if (snapParams.nFeatureSnap() > 0)
839 nFeatIter = snapParams.nFeatureSnap();
842 Info<<
"Snapping to features in " << nFeatIter
843 <<
" iterations ..." <<
endl;
847 const labelList adaptPatchIDs(meshRefiner_.meshedPatches());
849 autoPtr<indirectPrimitivePatch> ppPtr
866 /
"pp_initial_" + meshRefiner_.timeName() +
".obj" 870 ppPtr().localFaces(),
871 ppPtr().localPoints(),
885 smoothLambdaMuPatchDisplacement
892 pointField ppLocalPoints(ppPtr().localPoints()+patchDisp);
894 const bool smoothInternal =
true;
907 autoPtr<displacementMotionSolver> motionPtr
926 motionPtr().pointDisplacement()
929 tmp<pointField> tnewPoints(motionPtr->newPoints());
937 patchDisp -= (ppLocalPoints-ppPtr().localPoints());
942 Info<<
"Writing smoothed mesh to time " 943 << meshRefiner_.timeName() <<
endl;
952 meshRefiner_.timeName()
959 Info<<
"Constructing mesh displacer ..." <<
endl;
960 Info<<
"Using mesh parameters " << motionDict <<
nl <<
endl;
962 autoPtr<displacementMotionSolver> motionPtr
972 autoPtr<motionSmoother> meshMoverPtr
979 motionPtr().pointDisplacement(),
987 Info<<
"Checking initial mesh ..." <<
endl;
996 Info<<
"Detected " << nInitErrors <<
" illegal faces" 997 <<
" (concave, zero area or negative cell pyramid volume)" 1001 Info<<
"Checked initial mesh in = " 1010 List<pointConstraint> patchConstraints(ppPtr().
nPoints());
1012 for (label iter = 0; iter < nFeatIter; iter++)
1015 <<
"Morph iteration " << iter <<
nl 1016 <<
"-----------------" <<
endl;
1026 const bool strictRegionSnap
1029 ? snapParams.strictRegionSnap()
1037 globalToMasterPatch_,
1038 globalToSlavePatch_,
1048 if (snapParams.detectNearSurfacesSnap())
1066 DynamicList<label> splitFaces;
1068 DynamicList<labelPair> splits;
1070 DynamicList<labelPair> splitPatches;
1076 disp = calcNearestSurfaceFeature
1084 scalar(iter+1)/nFeatIter,
1112 patchFeaturePoint = ppLocalPoints+patchAttraction;
1119 /
"calcNearestSurfaceFeature" 1120 + meshRefiner_.timeName()
1123 forAll(ppLocalPoints, pointi)
1125 const point& pt = ppLocalPoints[pointi];
1138 polyTopoChange meshMod(
mesh);
1141 meshRefiner_.doSplitFaces
1150 const Map<label> oldMeshPointMap(ppPtr->meshPointMap());
1151 Pout<<
"old pp points:" << ppPtr->nPoints()
1152 <<
" oldMeshPointMap:" << oldMeshPointMap.size()
1156 meshMoverPtr.clear();
1163 autoPtr<mapPolyMesh> mapPtr = meshMod.changeMesh(
mesh,
false);
1164 mapPolyMesh& map = *mapPtr;
1170 if (map.hasMotionPoints())
1185 DynamicList<label> changedFaces(splitFaces.size());
1186 Map<label> splitFacesMap(splitFaces.size());
1189 splitFacesMap.insert(splitFaces[i], i);
1191 forAll(map.faceMap(), facei)
1193 if (splitFacesMap.find(map.faceMap()[facei]))
1195 changedFaces.append(facei);
1199 meshRefiner_.updateMesh
1202 meshRefiner_.growFaceCellFace(changedFaces)
1209 Info<<
"Writing split-faces mesh to time " 1210 << meshRefiner_.timeName() <<
endl;
1228 Info<<
"Updating for face-splitting" <<
endl;
1231 forAll(internalBaffles, i)
1234 baffle.
first() = map.reverseFaceMap()[baffle.first()];
1235 baffle.second() = map.reverseFaceMap()[baffle.second()];
1240 motionPtr = makeMotionSolver
1254 motionPtr().pointDisplacement(),
1260 const auto&
mp = ppPtr->meshPoints();
1267 ppMap[i] = oldMeshPointMap[
mp[i]];
1296 Info<<
"DONE Updating for face-splitting" <<
endl;
1335 motionPtr().pointDisplacement()
1339 tmp<pointField> tnewPoints(motionPtr->newPoints());
1356 const vectorField newDisp(tnewPoints()-meshMoverPtr().oldPoints());
1358 meshMoverPtr().displacement().vectorField::operator=(newDisp);
1359 meshMoverPtr().setDisplacement(disp);
1362 const bool meshOk = scaleMesh
1373 <<
"Did not successfully snap mesh." 1374 <<
" Continuing to snap to resolve easy" <<
nl 1375 <<
" surfaces but the" 1376 <<
" resulting mesh will not satisfy your quality" 1377 <<
" constraints" <<
nl <<
endl;
1381 meshMoverPtr().correct();
1388 patchDisp -= (ppLocalPoints-ppPtr().localPoints());
1393 Info<<
"Writing partially moved mesh to time " 1394 << meshRefiner_.timeName() <<
endl;
1403 meshRefiner_.timeName()
1410 Info<<
nl <<
"Checking moved mesh ..." <<
endl;
1422 const label nWrong(
returnReduce(wrongFaces.size(), sumOp<label>()));
1423 Info<<
"Detected " << nWrong
1425 <<
" (concave, zero area or negative cell pyramid volume)" 1432 for (
const label facei : wrongFaces)
1437 decomposeCell.
set(own);
1444 decomposeCell.
set(nei);
1448 Pout<<
"spliyyinG :" << decomposeCell.count() <<
" cells" 1451 tetDecomposer tetDecomp(
mesh);
1452 polyTopoChange meshMod(
mesh);
1453 tetDecomp.setRefinement
1461 const Map<label> oldMeshPointMap(ppPtr->meshPointMap());
1463 Pout<<
"old pp points:" << ppPtr->nPoints()
1464 <<
" oldMeshPointMap:" << oldMeshPointMap.size()
1468 meshMoverPtr.clear();
1475 autoPtr<mapPolyMesh> mapPtr = meshMod.changeMesh(
mesh,
false);
1476 mapPolyMesh& map = *mapPtr;
1482 if (map.hasMotionPoints())
1496 tetDecomp.updateMesh(map);
1499 forAll(map.cellMap(), celli)
1501 if (decomposeCell[map.cellMap()[celli]])
1510 orEqOp<unsigned int>()
1513 Pout<<
"isChangedFace :" << decomposeCell.count() <<
" faces" 1518 meshRefiner_.updateMesh(map, isChangedFace.toc());
1524 Info<<
"Writing tet-decomp mesh to time " 1525 << meshRefiner_.timeName() <<
endl;
1542 Info<<
"Updating for tet-decomp" <<
endl;
1545 forAll(internalBaffles, i)
1548 baffle.
first() = map.reverseFaceMap()[baffle.first()];
1549 baffle.second() = map.reverseFaceMap()[baffle.second()];
1554 Pout<<
"new pp points:" << ppPtr->nPoints()
1555 <<
" new meshPointMap:" << ppPtr->meshPointMap().size()
1557 const auto&
mp = ppPtr->meshPoints();
1564 const label oldMeshPointi = map.pointMap()[
mp[i]];
1565 const auto mpFnd = oldMeshPointMap.find(oldMeshPointi);
1598 snapDist = calcSnapDistance(
mesh, snapParams, ppPtr());
1601 Info<<
"DONE Updating for tet-decomp" <<
endl;
1831 addPatchCellLayer addLayer(
mesh);
1834 const Map<label> oldMeshPointMap(ppPtr->meshPointMap());
1836 meshMoverPtr.clear();
1841 wantedThickness(ppPtr(), 1
e-3)
1844 autoPtr<mapPolyMesh> mapPtr = addBufferLayers
1859 forAll(addedPoints, oldPatchPointi)
1861 const label
newPointi = addedPoints[oldPatchPointi].last();
1862 const label newPatchPointi = ppPtr().meshPointMap()[
newPointi];
1863 ppMap[newPatchPointi] = oldPatchPointi;
1889 const bool snapToGeometry =
true;
1905 autoPtr<displacementMotionSolver> motionPtr
1921 patchFeaturePoint-ppLocalPoints,
1924 motionPtr().pointDisplacement()
1933 /
"buffer_layer_new_projection" 1934 + meshRefiner_.timeName()
1937 forAll(ppLocalPoints, pointi)
1939 const point& pt = ppLocalPoints[pointi];
1940 str.write(
linePointRef(pt, patchFeaturePoint[pointi]));
1942 Pout<<
"** writing mapped attraction to " << str.
name() <<
endl;
1947 tmp<pointField> tnewPoints(motionPtr->newPoints());
1955 patchDisp -= (ppLocalPoints-ppPtr().localPoints());
1960 Info<<
"Writing smoothed LAYER mesh to time " 1961 << meshRefiner_.timeName() <<
endl;
1970 meshRefiner_.timeName()
1978 autoPtr<mapPolyMesh> mapPtr = meshRefiner_.mergeZoneBaffles
1989 Info<<
"Writing baffle-merged mesh to time " 1990 << meshRefiner_.timeName() <<
endl;
1999 meshRefiner_.timeName()
2007 labelList duplicateFace(getInternalOrBaffleDuplicateFace());
2009 repatchToSurface(snapParams, adaptPatchIDs, duplicateFace);
static bool checkMesh(const bool report, const polyMesh &mesh, const dictionary &dict, labelHashSet &wrongFaces, const bool dryRun=false)
Check mesh with mesh settings in dict. Collects incorrect faces.
const T & first() const noexcept
Access the first element.
label nPoints() const
Number of points supporting patch faces.
const List< face_type > & localFaces() const
Return patch faces addressing into local point list.
void size(const label n)
Older name for setAddressableSize.
fileName path() const
Return path = rootPath/caseName. Same as TimePaths::path()
errorManipArg< error, int > exit(error &err, const int errNo=1)
const fileName & facesInstance() const
Return the current instance directory for faces.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
const Field< point_type > & localPoints() const
Return pointField of points in patch.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
virtual const labelList & faceNeighbour() const
Return face neighbour.
List< edge > edgeList
List of edge.
static const weightedPosition zero
vectorIOField pointIOField
pointIOField is a vectorIOField.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Unit conversion functions.
static FOAM_NO_DANGLING_REFERENCE const pointConstraints & New(const pointMesh &mesh, Args &&... args)
Get existing or create MeshObject registered with typeName.
constexpr char nl
The newline '\n' character (0x0a)
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Ostream & endl(Ostream &os)
Add newline and flush stream.
virtual void movePoints(const pointField &)
Move points, returns volumes swept by faces in motion.
#define addProfiling(Name,...)
Define profiling trigger with specified name and description string. The description is generated by ...
static writeType writeLevel()
Get/set write level.
void clearOut(const bool isMeshUpdate=false)
Clear all geometry and addressing.
GeometricField< vector, pointPatchField, pointMesh > pointVectorField
List< labelPair > labelPairList
List of labelPair.
const cellList & cells() const
GeometricBoundaryField< vector, pointPatchField, pointMesh > Boundary
Type of boundary fields.
Ignore writing from objectRegistry::writeObject()
const Time & time() const
Return the top-level database.
label nFaces() const noexcept
Number of mesh faces.
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
A PrimitivePatch with an IndirectList for the faces, const reference for the point field...
virtual const fileName & name() const override
Get the name of the output serial stream. (eg, the name of the Fstream file name) ...
List< labelList > labelListList
List of labelList.
bool isInternalFace(const label faceIndex) const noexcept
Return true if given face label is internal to the mesh.
const labelList & meshPoints() const
Return labelList of mesh points in patch.
static labelPairList findDuplicateFacePairs(const polyMesh &)
Helper routine to find all baffles (two boundary faces.
virtual const pointField & points() const
Return raw points.
#define forAll(list, i)
Loop across all elements in list.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
static void updateList(const labelList &newToOld, const T &nullValue, List< T > &elems)
Helper: reorder list according to map.
vectorField pointField
pointField is a vectorField.
const dimensionedScalar e
Elementary charge.
static labelListList globalEdgeFaces(const polyMesh &, const globalIndex &globalFaces, const indirectPrimitivePatch &pp, const bitSet &orientation)
Per patch edge the pp faces (in global indices) using it.
virtual void updateMesh(const mapPolyMesh &mpm)
Update mesh corresponding to the given map.
FaceMergeType
Enumeration for what to do with co-planar patch faces on a single.
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
dimensionedScalar cos(const dimensionedScalar &ds)
line< point, const point & > linePointRef
A line using referred points.
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...
dimensionedScalar lambda("lambda", dimTime/sqr(dimLength), laminarTransport)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
label size() const noexcept
The number of entries in the list.
virtual const labelList & faceOwner() const
Return face owner.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
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.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
int debug
Static debugging option.
Pair< label > labelPair
A pair of labels.
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
static autoPtr< indirectPrimitivePatch > makePatch(const polyMesh &, const labelList &)
Create patch from set of patches.
double cpuTimeIncrement() const
Return CPU time [seconds] since last call to cpuTimeIncrement(), resetCpuTimeIncrement().
static void determineSidePatches(meshRefinement &meshRefiner, const globalIndex &globalFaces, const labelListList &edgeGlobalFaces, const indirectPrimitivePatch &pp, labelList &edgePatchID, labelList &edgeZoneID, boolList &edgeFlip, labelList &inflateFaceID)
Helper: see what zones and patches edges should be extruded into.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
const dimensionedScalar mu
Atomic mass unit.
bool moving() const noexcept
Is mesh moving.
pointField points0(pointIOField(IOobject("points", mesh.time().constant(), polyMesh::meshSubDir, mesh, IOobject::MUST_READ, IOobject::NO_WRITE, IOobject::NO_REGISTER)))
vector point
Point is a vector.
void setInstance(const fileName &instance, const IOobjectOption::writeOption wOpt=IOobject::AUTO_WRITE)
Set the instance for mesh files.
#define WarningInFunction
Report a warning using Foam::Warning.
label nCells() const noexcept
Number of mesh cells.
loopControl iters(runTime, aMesh.solutionDict(), "solution")
const std::string patch
OpenFOAM patch number as a std::string.
static autoPtr< displacementMotionSolver > New(const word &solverTypeName, const polyMesh &, const IOdictionary &, const pointVectorField &pointDisplacement, const pointIOField &points0)
Select constructed from polyMesh, dictionary and components.
messageStream Info
Information stream (stdout output on master, null elsewhere)
writeType
Enumeration for what to write. Used as a bit-pattern.
Field< vector > vectorField
Specialisation of Field<T> for vector.
debugType
Enumeration for what to debug. Used as a bit-pattern.
std::enable_if_t< std::is_same_v< bool, TypeT >, bool > set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
static void syncPoints(const polyMesh &mesh, List< weightedPosition > &)
Synchronisation for mesh point positions.
List< label > labelList
A List of labels.
static tmp< pointVectorField > makeDisplacementField(const pointMesh &pMesh, const labelList &adaptPatchIDs)
Helper function to make a pointVectorField with correct.
A class for managing temporary objects.
static bool test(const UList< face > &faces)
Test if given list of faces satisfies criteria for TET. (4 tri)
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
List< bool > boolList
A List of bools.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
const dimensionedScalar mp
Proton mass.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
static constexpr const zero Zero
Global zero (0)