53 hexMeshSmootherMotionSolver,
60 hexMeshSmootherMotionSolver,
76 const auto&
pbm =
mesh.boundaryMesh();
79 for (
const auto&
pp :
pbm)
81 if (!polyPatch::constraintType(
pp.type()))
91Foam::hexMeshSmootherMotionSolver::makePatch
100 bitSet isPatchFace(
mesh.nFaces());
105 const polyPatch&
pp =
mesh.boundaryMesh()[patchi];
106 isPatchFace.set(
pp.range());
109 const auto& fzs =
mesh.faceZones();
110 for (
const label zonei :
zoneIDs)
112 isPatchFace.set(fzs[zonei]);
115 syncTools::syncFaceList(
mesh, isPatchFace, orEqOp<unsigned int>());
117 const labelList patchFaces(isPatchFace.sortedToc());
119 return autoPtr<indirectPrimitivePatch>::New
121 IndirectList<face>(
mesh.faces(), patchFaces),
127void Foam::hexMeshSmootherMotionSolver::checkMesh
129 const pointField& currentPoints,
130 const vectorField& fCtrs,
131 const vectorField& fAreas,
132 const vectorField& cellCtrs,
134 labelHashSet& markedFaces,
143 markedPoints =
false;
187 tmp<scalarField> tfaceQ
189 pointSmoother_->faceQuality
198 const auto& faceQ = tfaceQ();
203 if (faceQ[facei] < VSMALL)
205 markedFaces.insert(facei);
206 markedPoints.set(
mesh().faces()[facei]);
211 syncTools::syncPointList
215 orEqOp<unsigned int>(),
221 bitSet isMarkedFace(
mesh().nFaces());
222 isMarkedFace.set(markedFaces.toc());
223 syncTools::syncFaceList
227 orEqOp<unsigned int>()
229 markedFaces.insert(isMarkedFace.toc());
252bool Foam::hexMeshSmootherMotionSolver::relax
254 const scalarList& relaxationFactors,
255 const bitSet& pointsToRelax,
256 const pointField& initialPoints,
257 const pointField& wantedPoints,
258 pointField& relaxedPoints,
259 labelList& relaxationLevel
265 relaxedPoints = wantedPoints;
275 reinterpret_cast<const fvMesh&
>(
mesh()).geometry();
302 Pout<<
"** hexMeshSmootherMotionSolver::relax : errorfaces:"
303 << markedFaces.size()
304 <<
" errorpoints:" << markedPoints.count() <<
endl;
313 relaxationLevel = -1;
314 for (
const label pointi : pointsToRelax)
316 relaxationLevel[pointi] = 0;
319 syncTools::syncPointList
333 bool complete(
false);
341 forAll(relaxationLevel, pointi)
343 if (relaxationLevel[pointi] >= 0)
347 relaxationFactors[relaxationLevel[pointi]]
350 relaxedPoints[pointi] =
351 (1 -
x)*initialPoints[pointi]
352 +
x*wantedPoints[pointi];
364 reinterpret_cast<const fvMesh&
>(
mesh()).geometry();
393 for (
const label pointi : markedPoints)
395 if (relaxationLevel[pointi] < relaxationFactors.size() - 1)
397 ++relaxationLevel[pointi];
408 UPstream::reduceAnd(complete);
411 syncTools::syncPointList
421 const label
count(countPos(relaxationLevel));
422 const bool converged(count == 0);
435Foam::label Foam::hexMeshSmootherMotionSolver::countPos
437 const labelList& elems
441 for (
const label elem : elems)
455 const labelList& elems
459 for (
const label elem : elems)
467 Pstream::listReduce(
n, sumOp<label>());
472void Foam::hexMeshSmootherMotionSolver::select
474 const labelUList& lst,
479 isVal.set(lst.size());
483 isVal[i] = (lst[i] == val);
488void Foam::hexMeshSmootherMotionSolver::laplaceSmooth
491 const pointField& initialPoints,
492 pointField& newPoints
498 <<
" initial:" << initialPoints.size() <<
exit(FatalError);
501 newPoints.setSize(initialPoints.size());
505 DynamicList<label> storage;
506 forAll(pointTypes_, pointi)
508 if (pointTypes_[pointi] == INTERIOR)
510 const labelList& pPoints =
mesh().pointPoints(pointi, storage);
511 for (
const label otherPointi : pPoints)
513 if (isMasterPoint_[otherPointi])
515 newPoints[pointi] += initialPoints[otherPointi];
526 syncTools::syncPointList
533 syncTools::syncPointList
545 newPoints[pointi] = initialPoints[pointi];
550 newPoints[pointi] /=
n[pointi];
556void Foam::hexMeshSmootherMotionSolver::featLaplaceSmooth
558 const indirectPrimitivePatch&
pp,
559 const pointField& initialPoints,
560 pointField& newPoints
563 if (initialPoints.size() !=
pp.nPoints())
566 <<
" initial:" << initialPoints.size() <<
exit(FatalError);
569 newPoints.setSize(
pp.nPoints());
577 forAll(pointEdges, pointi)
579 const label myConstraint = pointTypes_[meshPoints[pointi]];
580 if (myConstraint != INTERIOR)
582 const labelList& pEdges = pointEdges[pointi];
586 for (
const label edgei : pEdges)
588 const label otherPointi = edges[edgei].otherVertex(pointi);
589 const label otherMeshPointi = meshPoints[otherPointi];
590 const label otherConstraint = pointTypes_[otherMeshPointi];
594 (otherConstraint != INTERIOR)
595 && (myConstraint <= otherConstraint)
596 && isMasterPoint_[otherMeshPointi]
602 newPoints[pointi] += initialPoints[otherPointi];
610 syncTools::syncPointList
618 syncTools::syncPointList
633 newPoints[pointi] = initialPoints[pointi];
638 newPoints[pointi] /=
n[pointi];
645void Foam::hexMeshSmootherMotionSolver::snapBoundaryPoints
648 const pointField& initialPoints,
649 pointField& newPoints
652 if (initialPoints.size() != pointDisplacement_.mesh().size())
655 <<
"mesh.nPoints():" << pointDisplacement_.mesh().size()
656 <<
" initial:" << initialPoints.size() <<
exit(FatalError);
667 pointDisplacement_.primitiveFieldRef() = initialPoints-
points0();
669 pointDisplacement_.correctBoundaryConditions();
672 newPoints =
points0() + pointDisplacement().internalField();
681 UIndirectList<point>(newPoints, mp) = d;
714void Foam::hexMeshSmootherMotionSolver::emptyCorrectPoints
716 pointVectorField& pointDisplacement
721 auto&
fld = pointDisplacement.primitiveFieldRef();
722 for (
const auto& ppf : pointDisplacement.boundaryField())
724 if (isA<emptyPointPatchVectorField>(ppf))
726 const auto&
mp = ppf.patch().meshPoints();
730 ppf.patch().applyConstraint(i, pc);
731 fld[
mp[i]] = pc.constrainDisplacement(
fld[mp[i]]);
737 twoDCorrectPoints(wantedPoints);
744Foam::hexMeshSmootherMotionSolver::
745hexMeshSmootherMotionSolver
747 const polyMesh&
mesh,
748 const IOdictionary&
dict
751 displacementMotionSolver(
mesh,
dict, typeName),
752 pointSmoother_(pointSmoother::
New(
mesh, coeffDict())),
755 coeffDict().
get<label>(
"nPointSmootherIter")
757 relaxationFactors_(coeffDict().
get<
scalarList>(
"relaxationFactors")),
776 snapScale_(Function1<scalar>::
New(
"snapScale", coeffDict())),
777 isMasterPoint_(syncTools::getMasterPoints(
mesh)),
785 nonConstraintPatches(
mesh),
812 pointTypes_.setSize(pMesh.size());
813 pointTypes_ = INTERIOR;
815 for (
const auto&
pp : pMesh.boundary())
825 for (
const auto&
pp : pMesh.boundary())
830 const auto& constraints = meshPointPtr->constraints();
831 const auto&
mp = meshPointPtr->meshPoints();
835 pointTypes_[
mp[i]] = pointType(constraints[i].first());
850 select(pointTypes_, POINT, isVal);
852 select(pointTypes_, EDGE, isVal);
854 select(pointTypes_, SURFACE, isVal);
856 select(pointTypes_, INTERIOR, isVal);
858 Info<<
"Attraction:" <<
nl
859 <<
" feature point:" << nFeatPoint <<
nl
860 <<
" feature edge :" << nFeatEdge <<
nl
861 <<
" surface :" << nSurface <<
nl
862 <<
" none :" << nInternal
867Foam::hexMeshSmootherMotionSolver::
868hexMeshSmootherMotionSolver
870 const polyMesh&
mesh,
871 const IOdictionary&
dict,
872 const pointVectorField& pointDisplacement,
876 displacementMotionSolver(
mesh,
dict, pointDisplacement,
points0, typeName),
877 pointSmoother_(pointSmoother::
New(
mesh, coeffDict())),
888 coeffDict().
get<label>(
"nPointSmootherIter")
890 relaxationFactors_(coeffDict().
get<
scalarList>(
"relaxationFactors")),
909 snapScale_(Function1<scalar>::
New(
"snapScale", coeffDict())),
910 isMasterPoint_(syncTools::getMasterPoints(
mesh)),
918 nonConstraintPatches(
mesh),
943 pointTypes_ = INTERIOR;
945 for (
const auto&
pp : pMesh.boundary())
955 for (
const auto&
pp : pMesh.boundary())
960 const auto& constraints = meshPointPtr->constraints();
961 const auto&
mp = meshPointPtr->meshPoints();
965 pointTypes_[
mp[i]] = pointType(constraints[i].first());
980 select(pointTypes_, POINT, isVal);
982 select(pointTypes_, EDGE, isVal);
984 select(pointTypes_, SURFACE, isVal);
986 select(pointTypes_, INTERIOR, isVal);
988 Info<<
"Attraction:" <<
nl
989 <<
" feature point:" << nFeatPoint <<
nl
990 <<
" feature edge :" << nFeatEdge <<
nl
991 <<
" surface :" << nSurface <<
nl
992 <<
" none :" << nInternal
999Foam::hexMeshSmootherMotionSolver::
1000~hexMeshSmootherMotionSolver()
1007Foam::hexMeshSmootherMotionSolver::curPoints()
const
1010 return relaxedPoints_;
1014void Foam::hexMeshSmootherMotionSolver::solve()
1031 bitSet isInternalPoint;
1032 select(pointTypes_, INTERIOR, isInternalPoint);
1045 const label nRelaxed = countPos(relaxationLevel_);
1062 laplaceSmooth(INTERIOR, initialPoints, movedPoints);
1089 const scalar scale = snapScale_->value(
mesh().time().
timeIndex());
1093 snapBoundaryPoints(scale, initialPoints, movedPoints);
1125 UIndirectList<point>(movedPoints, mp) = bndMovedPoints;
1164 UIndirectList<point>(movedPoints, mp) = bndMovedPoints;
1196 const scalar scale = snapScale_->value(
mesh().time().
timeIndex());
1200 snapBoundaryPoints(scale, relaxedPoints_, movedPoints);
1223 movedPoints = relaxedPoints_;
1225 for(label i = 0; i < nPointSmootherIter_; i ++)
1231 reinterpret_cast<const fvMesh&
>(
mesh()).geometry();
1244 pointSmoother_->update
1256 emptyCorrectPoints(pointDisplacement());
1259 movedPoints =
points0() + pointDisplacement().internalField();
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
Info<< nl;Info<< "Write faMesh in vtk format:"<< nl;{ vtk::uindirectPatchWriter writer(aMesh.patch(), fileName(aMesh.time().globalPath()/vtkBaseFileName));writer.writeGeometry();globalIndex procAddr(aMesh.nFaces());labelList cellIDs;if(UPstream::master()) { cellIDs.resize(procAddr.totalSize());for(const labelRange &range :procAddr.ranges()) { auto slice=cellIDs.slice(range);slice=identity(range);} } writer.beginCellData(4);writer.writeProcIDs();writer.write("cellID", cellIDs);writer.write("area", aMesh.S().field());writer.write("normal", aMesh.faceAreaNormals());writer.beginPointData(1);writer.write("normal", aMesh.pointAreaNormals());Info<< " "<< writer.output().name()<< nl;}{ vtk::lineWriter writer(aMesh.points(), aMesh.edges(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edges")));writer.writeGeometry();writer.beginCellData(4);writer.writeProcIDs();{ Field< scalar > fld(faMeshTools::flattenEdgeField(aMesh.magLe(), true))
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
const polyBoundaryMesh & pbm
@ READ_IF_PRESENT
Reading is optional [identical to LAZY_READ].
static FOAM_NO_DANGLING_REFERENCE const pointMesh & New(const polyMesh &mesh, Args &&... args)
const labelList & meshPoints() const
Return labelList of mesh points in patch.
A List with indirect addressing. Like IndirectList but does not store addressing.
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...
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Virtual base class for displacement motion solver.
Virtual base class for mesh motion solver.
Mesh representing a set of points created from polyMesh.
label nPoints() const noexcept
Number of mesh points.
A class for managing temporary objects.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const labelIOList & zoneIDs
return returnReduce(nRefine-oldNRefine, sumOp< label >())
List< bool > select(const label n, const labelUList &locations)
Construct a selection list of bools (all false) with the given pre-size, subsequently add specified l...
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
const dimensionedScalar mp
Proton mass.
List< edge > edgeList
List of edge.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
List< labelList > labelListList
List of labelList.
List< label > labelList
A List of labels.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
messageStream Info
Information stream (stdout output on master, null elsewhere).
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
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.
Ostream & endl(Ostream &os)
Add newline and flush stream.
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
A PrimitivePatch with an IndirectList for the faces, const reference for the point field.
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...
Field< vector > vectorField
Specialisation of Field<T> for vector.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
vectorField pointField
pointField is a vectorField.
errorManipArg< error, int > exit(error &err, const int errNo=1)
List< scalar > scalarList
List of scalar.
constexpr char nl
The newline '\n' character (0x0a).
#define forAll(list, i)
Loop across all elements in list.
const scalarField & cellVols
Unit conversion functions.
pointField points0(pointIOField(IOobject("points", mesh.time().constant(), polyMesh::meshSubDir, mesh, IOobject::MUST_READ, IOobject::NO_WRITE, IOobject::NO_REGISTER)))