/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.1
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see .
Class
meshDualiser
\*---------------------------------------------------------------------------*/
#include "meshDualiser.H"
#include "meshTools.H"
#include "polyMesh.H"
#include "directTopoChange.H"
#include "mapPolyMesh.H"
#include "edgeFaceCirculator.H"
#include "mergePoints.H"
#include "OFstream.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::meshDualiser, 0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::meshDualiser::checkPolyTopoChange(const directTopoChange& meshMod)
{
// Assume no removed points
pointField points(meshMod.points().size());
forAll(meshMod.points(), i)
{
points[i] = meshMod.points()[i];
}
labelList oldToNew;
pointField newPoints;
bool hasMerged = mergePoints
(
points,
1E-6,
false,
oldToNew,
newPoints
);
if (hasMerged)
{
labelListList newToOld(invertOneToMany(newPoints.size(), oldToNew));
forAll(newToOld, newI)
{
if (newToOld[newI].size() != 1)
{
FatalErrorIn
(
"meshDualiser::checkPolyTopoChange(const directTopoChange&)"
) << "duplicate verts:" << newToOld[newI]
<< " coords:"
<< UIndirectList(points, newToOld[newI])()
<< abort(FatalError);
}
}
}
}
// Dump state so far.
void Foam::meshDualiser::dumpPolyTopoChange
(
const directTopoChange& meshMod,
const fileName& prefix
)
{
OFstream str1(prefix + "Faces.obj");
OFstream str2(prefix + "Edges.obj");
Info<< "Dumping current directTopoChange. Faces to " << str1.name()
<< " , points and edges to " << str2.name() << endl;
const DynamicList& points = meshMod.points();
forAll(points, pointI)
{
meshTools::writeOBJ(str1, points[pointI]);
meshTools::writeOBJ(str2, points[pointI]);
}
const DynamicList& faces = meshMod.faces();
forAll(faces, faceI)
{
const face& f = faces[faceI];
str1<< 'f';
forAll(f, fp)
{
str1<< ' ' << f[fp]+1;
}
str1<< nl;
str2<< 'l';
forAll(f, fp)
{
str2<< ' ' << f[fp]+1;
}
str2<< ' ' << f[0]+1 << nl;
}
}
//- Given cell and point on mesh finds the corresponding dualCell. Most
// points become only one cell but the feature points might be split.
Foam::label Foam::meshDualiser::findDualCell
(
const label cellI,
const label pointI
) const
{
const labelList& dualCells = pointToDualCells_[pointI];
if (dualCells.size() == 1)
{
return dualCells[0];
}
else
{
label index = findIndex(mesh_.pointCells()[pointI], cellI);
return dualCells[index];
}
}
// Helper function to generate dualpoints on all boundary edges emanating
// from (boundary & feature) point
void Foam::meshDualiser::generateDualBoundaryEdges
(
const PackedBoolList& isBoundaryEdge,
const label pointI,
directTopoChange& meshMod
)
{
const labelList& pEdges = mesh_.pointEdges()[pointI];
forAll(pEdges, pEdgeI)
{
label edgeI = pEdges[pEdgeI];
if (edgeToDualPoint_[edgeI] == -1 && isBoundaryEdge.get(edgeI) == 1)
{
const edge& e = mesh_.edges()[edgeI];
edgeToDualPoint_[edgeI] = meshMod.addPoint
(
e.centre(mesh_.points()),
pointI, // masterPoint
-1, // zoneID
true // inCell
);
}
}
}
// Return true if point on face has same dual cells on both owner and neighbour
// sides.
bool Foam::meshDualiser::sameDualCell
(
const label faceI,
const label pointI
) const
{
if (!mesh_.isInternalFace(faceI))
{
FatalErrorIn("sameDualCell(const label, const label)")
<< "face:" << faceI << " is not internal face."
<< abort(FatalError);
}
label own = mesh_.faceOwner()[faceI];
label nei = mesh_.faceNeighbour()[faceI];
return findDualCell(own, pointI) == findDualCell(nei, pointI);
}
Foam::label Foam::meshDualiser::addInternalFace
(
const label masterPointI,
const label masterEdgeI,
const label masterFaceI,
const bool edgeOrder,
const label dualCell0,
const label dualCell1,
const DynamicList