Commit 48055b2d authored by mattijs's avatar mattijs Committed by Andrew Heather
Browse files

ENH: distributedTriSurfaceMesh: auto-decomposition; inside/outside support

parent d4a97ecd
......@@ -471,6 +471,12 @@ public:
return nodes_[0].bb_;
}
//- Per node, per octant whether is fully inside/outside/mixed.
PackedList<2>& nodeTypes() const
{
return nodeTypes_;
}
// Conversions for entries in subNodes_.
......
......@@ -330,10 +330,10 @@ public:
mapDistribute();
//- Copy construct
mapDistribute(const mapDistribute& map);
explicit mapDistribute(const mapDistribute& map);
//- Move construct
mapDistribute(mapDistribute&& map);
explicit mapDistribute(mapDistribute&& map);
//- Move construct from components
mapDistribute
......
......@@ -128,6 +128,11 @@ public:
{
return true;
}
//- What is type of points outside bounds
virtual volumeType outsideVolumeType() const
{
return volumeType::OUTSIDE;
}
//- Range of local indices that can be returned.
virtual label size() const
......
......@@ -186,6 +186,12 @@ public:
return true;
}
//- What is type of points outside bounds
virtual volumeType outsideVolumeType() const
{
return volumeType::OUTSIDE;
}
//- Range of local indices that can be returned.
virtual label size() const
{
......
......@@ -158,6 +158,12 @@ public:
return true;
}
//- What is type of points outside bounds
virtual volumeType outsideVolumeType() const
{
return volumeType::OUTSIDE;
}
//- Range of local indices that can be returned.
virtual label size() const
{
......
......@@ -141,6 +141,12 @@ public:
return false;
}
//- What is type of points outside bounds
virtual volumeType outsideVolumeType() const
{
return volumeType::UNKNOWN;
}
//- Range of local indices that can be returned.
virtual label size() const
{
......
......@@ -124,6 +124,12 @@ public:
return true;
}
//- What is type of points outside bounds
virtual volumeType outsideVolumeType() const
{
return volumeType::OUTSIDE;
}
//- Range of local indices that can be returned.
virtual label size() const;
......
......@@ -126,6 +126,12 @@ public:
return false;
}
//- What is type of points outside bounds
virtual volumeType outsideVolumeType() const
{
return volumeType::UNKNOWN;
}
//- Range of local indices that can be returned.
virtual label size() const
{
......
......@@ -152,6 +152,12 @@ public:
return false;
}
//- What is type of points outside bounds
virtual volumeType outsideVolumeType() const
{
return volumeType::UNKNOWN;
}
//- Range of local indices that can be returned.
virtual label size() const
{
......
......@@ -131,6 +131,12 @@ public:
return true;
}
//- What is type of points outside bounds
virtual volumeType outsideVolumeType() const
{
return volumeType::OUTSIDE;
}
//- Range of local indices that can be returned.
virtual label size() const
{
......
......@@ -144,6 +144,12 @@ public:
return true;
}
//- What is type of points outside bounds
virtual volumeType outsideVolumeType() const
{
return volumeType::OUTSIDE;
}
//- Range of local indices that can be returned.
virtual label size() const
{
......
......@@ -176,13 +176,13 @@ public:
}
//- Return const reference to boundBox
const boundBox& bounds() const
virtual const boundBox& bounds() const
{
return bounds_;
}
//- Return non-const access to the boundBox to allow it to be set.
boundBox& bounds()
virtual boundBox& bounds()
{
return bounds_;
}
......@@ -194,6 +194,10 @@ public:
// This is false for the base class.
virtual bool hasVolumeType() const;
//- If surface supports volume queries, what is type of points outside
// bounds
virtual volumeType outsideVolumeType() const = 0;
//- Range of local indices that can be returned
virtual label size() const = 0;
......
......@@ -181,6 +181,12 @@ public:
return false;
}
//- What is type of points outside bounds
virtual volumeType outsideVolumeType() const
{
return volumeType::UNKNOWN;
}
//- Range of local indices that can be returned.
virtual label size() const;
......
......@@ -166,6 +166,12 @@ public:
return surface().hasVolumeType();
}
//- What is type of points outside bounds
virtual volumeType outsideVolumeType() const
{
return surface().outsideVolumeType();
}
//- Range of local indices that can be returned.
virtual label size() const
{
......
......@@ -71,7 +71,7 @@ Foam::fileName Foam::triSurfaceMesh::checkFile
Foam::fileName Foam::triSurfaceMesh::relativeFilePath
(
const regIOobject& io,
const IOobject& io,
const fileName& f,
const bool isGlobal
)
......@@ -96,7 +96,7 @@ Foam::fileName Foam::triSurfaceMesh::relativeFilePath
Foam::fileName Foam::triSurfaceMesh::checkFile
(
const regIOobject& io,
const IOobject& io,
const dictionary& dict,
const bool isGlobal
)
......@@ -156,6 +156,13 @@ bool Foam::triSurfaceMesh::addFaceToEdge
bool Foam::triSurfaceMesh::isSurfaceClosed() const
{
if (debug)
{
Pout<< "triSurfaceMesh::isSurfaceClosed:"
<< " determining closedness for surface with "
<< triSurface::size() << " triangles" << endl;
}
const pointField& pts = triSurface::points();
// Construct pointFaces. Let's hope surface has compact point
......@@ -196,6 +203,11 @@ bool Foam::triSurfaceMesh::isSurfaceClosed() const
if (!okFace)
{
if (debug)
{
Pout<< "triSurfaceMesh::isSurfaceClosed :"
<< " surface is open" << endl;
}
return false;
}
}
......@@ -213,6 +225,11 @@ bool Foam::triSurfaceMesh::isSurfaceClosed() const
if (!okFace)
{
if (debug)
{
Pout<< "triSurfaceMesh::isSurfaceClosed :"
<< " surface is open" << endl;
}
return false;
}
}
......@@ -223,11 +240,21 @@ bool Foam::triSurfaceMesh::isSurfaceClosed() const
{
if (iter.val() != 2)
{
if (debug)
{
Pout<< "triSurfaceMesh::isSurfaceClosed :"
<< " surface is open" << endl;
}
return false;
}
}
}
if (debug)
{
Pout<< "triSurfaceMesh::isSurfaceClosed :"
<< " surface is closed" << endl;
}
return true;
}
......@@ -358,7 +385,7 @@ Foam::triSurfaceMesh::triSurfaceMesh
}
Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const bool isGlobal)
Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const readAction r)
:
// Find instance for triSurfaceMesh
searchableSurface(io),
......@@ -376,18 +403,79 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const bool isGlobal)
false // searchableSurface already registered under name
)
),
triSurface
(
checkFile(static_cast<const searchableSurface&>(*this), isGlobal)
),
triSurface(), // construct null
triSurfaceRegionSearch(static_cast<const triSurface&>(*this)),
minQuality_(-1),
surfaceClosed_(-1),
outsideVolType_(volumeType::UNKNOWN)
{
const pointField& pts = triSurface::points();
// Check IO flags
if (io.readOpt() != IOobject::NO_READ)
{
const bool searchGlobal(r == localOrGlobal || r == masterOnly);
const fileName actualFile
(
searchGlobal
? io.globalFilePath(typeName)
: io.localFilePath(typeName)
);
if (debug)
{
Pout<< "triSurfaceMesh(const IOobject& io) :"
<< " loading surface " << io.objectPath()
<< " local filePath:" << io.localFilePath(typeName)
<< " from:" << actualFile << endl;
}
if (searchGlobal && Pstream::parRun())
{
// Check where surface was found
const fileName localFile(io.localFilePath(typeName));
if (r == masterOnly && (actualFile != localFile))
{
// Found undecomposed surface. Load on master only
if (Pstream::master())
{
triSurface s2(actualFile);
triSurface::transfer(s2);
}
Pstream::scatter(triSurface::patches());
if (debug)
{
Pout<< "triSurfaceMesh(const IOobject& io) :"
<< " loaded triangles:" << triSurface::size() << endl;
}
}
else
{
// Read on all processors
triSurface s2(actualFile);
triSurface::transfer(s2);
if (debug)
{
Pout<< "triSurfaceMesh(const IOobject& io) :"
<< " loaded triangles:" << triSurface::size() << endl;
}
}
}
else
{
// Read on all processors
triSurface s2(actualFile);
triSurface::transfer(s2);
if (debug)
{
Pout<< "triSurfaceMesh(const IOobject& io) :"
<< " loaded triangles:" << triSurface::size() << endl;
}
}
}
bounds() = boundBox(pts, isGlobal);
const pointField& pts = triSurface::points();
bounds() = boundBox(pts, false);
}
......@@ -395,7 +483,7 @@ Foam::triSurfaceMesh::triSurfaceMesh
(
const IOobject& io,
const dictionary& dict,
const bool isGlobal
const readAction r
)
:
searchableSurface(io),
......@@ -413,26 +501,91 @@ Foam::triSurfaceMesh::triSurfaceMesh
false // searchableSurface already registered under name
)
),
triSurface
(
checkFile(static_cast<const searchableSurface&>(*this), dict, isGlobal)
),
triSurface(), // construct null
triSurfaceRegionSearch(static_cast<const triSurface&>(*this), dict),
minQuality_(-1),
surfaceClosed_(-1),
outsideVolType_(volumeType::UNKNOWN)
{
// Reading from supplied file name instead of objectPath/filePath
if (dict.readIfPresent("file", fName_, keyType::LITERAL))
// Check IO flags
if (io.readOpt() != IOobject::NO_READ)
{
fName_ = relativeFilePath
const bool searchGlobal(r == localOrGlobal || r == masterOnly);
fileName actualFile
(
static_cast<const searchableSurface&>(*this),
fName_,
isGlobal
searchGlobal
? io.globalFilePath(typeName)
: io.localFilePath(typeName)
);
// Reading from supplied file name instead of objectPath/filePath
if (dict.readIfPresent("file", fName_, keyType::LITERAL))
{
fName_ = relativeFilePath
(
static_cast<const searchableSurface&>(*this),
fName_,
searchGlobal
);
actualFile = fName_;
}
if (debug)
{
Pout<< "triSurfaceMesh(const IOobject& io, const dictionary&) :"
<< " loading surface " << io.objectPath()
<< " local filePath:" << io.localFilePath(typeName)
<< " from:" << actualFile << endl;
}
if (searchGlobal && Pstream::parRun())
{
// Check where surface was found
const fileName localFile(io.localFilePath(typeName));
if (r == masterOnly && (actualFile != localFile))
{
// Surface not loaded from processor directories -> undecomposed
// surface. Load on master only
if (Pstream::master())
{
triSurface s2(actualFile);
triSurface::transfer(s2);
}
Pstream::scatter(triSurface::patches());
if (debug)
{
Pout<< "triSurfaceMesh(const IOobject& io) :"
<< " loaded triangles:" << triSurface::size() << endl;
}
}
else
{
// Read on all processors
triSurface s2(actualFile);
triSurface::transfer(s2);
if (debug)
{
Pout<< "triSurfaceMesh(const IOobject& io) :"
<< " loaded triangles:" << triSurface::size() << endl;
}
}
}
else
{
// Read on all processors
triSurface s2(actualFile);
triSurface::transfer(s2);
if (debug)
{
Pout<< "triSurfaceMesh(const IOobject& io) :"
<< " loaded triangles:" << triSurface::size() << endl;
}
}
}
scalar scaleFactor = 0;
// Allow rescaling of the surface points
......@@ -445,8 +598,7 @@ Foam::triSurfaceMesh::triSurfaceMesh
}
const pointField& pts = triSurface::points();
bounds() = boundBox(pts, isGlobal);
bounds() = boundBox(pts, false);
// Have optional minimum quality for normal calculation
if (dict.readIfPresent("minQuality", minQuality_) && minQuality_ > 0)
......@@ -468,7 +620,7 @@ Foam::triSurfaceMesh::~triSurfaceMesh()
void Foam::triSurfaceMesh::clearOut()
{
outsideVolType_ = volumeType::UNKNOWN;
// Do not clear closedness status
triSurfaceRegionSearch::clearOut();
edgeTree_.clear();
triSurface::clearOut();
......@@ -539,7 +691,14 @@ bool Foam::triSurfaceMesh::overlaps(const boundBox& bb) const
void Foam::triSurfaceMesh::movePoints(const pointField& newPoints)
{
outsideVolType_ = volumeType::UNKNOWN;
if (debug)
{
Pout<< "triSurfaceMesh::movePoints :"
<< " moving at time " << objectRegistry::time().timeName()
<< endl;
}
// Preserve topological point status (surfaceClosed_, outsideVolType_)
// Update local information (instance, event number)
searchableSurface::instance() = objectRegistry::time().timeName();
......@@ -555,6 +714,10 @@ void Foam::triSurfaceMesh::movePoints(const pointField& newPoints)
triSurface::movePoints(newPoints);
bounds() = boundBox(triSurface::points(), false);
if (debug)
{
Pout<< "triSurfaceMesh::movePoints: finished moving points" << endl;
}
}
......@@ -563,6 +726,13 @@ Foam::triSurfaceMesh::edgeTree() const
{
if (edgeTree_.empty())
{
if (debug)
{
Pout<< "triSurfaceMesh::edgeTree :"
<< " constructing tree for " << nEdges() - nInternalEdges()
<< " boundary edges" << endl;
}
// Boundary edges
labelList bEdges
(
......@@ -592,6 +762,13 @@ Foam::triSurfaceMesh::edgeTree() const
bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
}
if (debug)
{
Pout<< "triSurfaceMesh::edgeTree : "
<< "calculating edge tree for bb:" << bb << endl;
}
scalar oldTol = indexedOctree<treeDataEdge>::perturbTol();
indexedOctree<treeDataEdge>::perturbTol() = tolerance();
......@@ -614,6 +791,14 @@ Foam::triSurfaceMesh::edgeTree() const
);
indexedOctree<treeDataEdge>::perturbTol() = oldTol;
if (debug)
{
Pout<< "triSurfaceMesh::edgeTree :"
<< " finished constructing tree for "
<< nEdges() - nInternalEdges()
<< " boundary edges" << endl;
}
}
return *edgeTree_;
......@@ -652,6 +837,40 @@ bool Foam::triSurfaceMesh::hasVolumeType() const
}
Foam::volumeType Foam::triSurfaceMesh::outsideVolumeType() const
{
if (outsideVolType_ == volumeType::UNKNOWN)
{
// Get point outside bounds()
const point outsidePt(bounds().max() + 0.5*bounds().span());
if (debug)
{
Pout<< "triSurfaceMesh::outsideVolumeType :"
<< " triggering outsidePoint:" << outsidePt
<< " orientation" << endl;
}
//outsideVolType_ = tree().shapes().getVolumeType(tree(), outsidePt);
// Note: do not use tree directly so e.g. distributedTriSurfaceMesh