/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM 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.
OpenFOAM 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 OpenFOAM. If not, see .
\*---------------------------------------------------------------------------*/
#include "meshDualiser.H"
#include "meshTools.H"
#include "polyMesh.H"
#include "polyTopoChange.H"
#include "mapPolyMesh.H"
#include "edgeFaceCirculator.H"
#include "mergePoints.H"
#include "OFstream.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(meshDualiser, 0);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::meshDualiser::checkPolyTopoChange(const polyTopoChange& meshMod)
{
// Assume no removed points
pointField points(meshMod.points().size());
forAll(meshMod.points(), i)
{
points[i] = meshMod.points()[i];
}
labelList oldToNew;
label nUnique = mergePoints
(
points,
1e-6,
false,
oldToNew
);
if (nUnique < points.size())
{
labelListList newToOld(invertOneToMany(nUnique, oldToNew));
forAll(newToOld, newI)
{
if (newToOld[newI].size() != 1)
{
FatalErrorInFunction
<< "duplicate verts:" << newToOld[newI]
<< " coords:"
<< UIndirectList(points, newToOld[newI])
<< abort(FatalError);
}
}
}
}
// Dump state so far.
void Foam::meshDualiser::dumpPolyTopoChange
(
const polyTopoChange& meshMod,
const fileName& prefix
)
{
OFstream str1(prefix + "Faces.obj");
OFstream str2(prefix + "Edges.obj");
Info<< "Dumping current polyTopoChange. 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;
}
}
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 = mesh_.pointCells()[pointi].find(celli);
return dualCells[index];
}
}
void Foam::meshDualiser::generateDualBoundaryEdges
(
const bitSet& isBoundaryEdge,
const label pointi,
polyTopoChange& meshMod
)
{
const labelList& pEdges = mesh_.pointEdges()[pointi];
forAll(pEdges, pEdgeI)
{
label edgeI = pEdges[pEdgeI];
if (edgeToDualPoint_[edgeI] == -1 && isBoundaryEdge.test(edgeI))
{
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))
{
FatalErrorInFunction
<< "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