mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge commit 'OpenCFD/master' into olesenm
This commit is contained in:
@ -223,10 +223,10 @@ Foam::autoHexMeshDriver::autoHexMeshDriver
|
|||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"abc", // dummy name
|
"abc", // dummy name
|
||||||
mesh_.time().timeName(), // directory
|
mesh_.time().findInstance("triSurface", word::null),// inst
|
||||||
"triSurface", // instance
|
"triSurface", // local
|
||||||
mesh_.time(), // registry
|
mesh_.time(), // registry
|
||||||
IOobject::MUST_READ,
|
IOobject::MUST_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
|
|||||||
@ -77,10 +77,11 @@ Foam::label Foam::autoRefineDriver::readFeatureEdges
|
|||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
featFileName, // name
|
featFileName, // name
|
||||||
mesh.time().constant(), // directory
|
mesh.time().findInstance("triSurface", featFileName),
|
||||||
"triSurface", // instance
|
// instance
|
||||||
mesh.time(), // registry
|
"triSurface", // local
|
||||||
|
mesh.time(), // registry
|
||||||
IOobject::MUST_READ,
|
IOobject::MUST_READ,
|
||||||
IOobject::NO_WRITE,
|
IOobject::NO_WRITE,
|
||||||
false
|
false
|
||||||
|
|||||||
@ -522,8 +522,8 @@ void Foam::refinementSurfaces::setMinLevelFields
|
|||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"minLevel",
|
"minLevel",
|
||||||
triMesh.objectRegistry::time().constant(),// directory
|
triMesh.objectRegistry::time().timeName(), // instance
|
||||||
"triSurface", // instance
|
"triSurface", // local
|
||||||
triMesh,
|
triMesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||||
|
-I$(LIB_SRC)/decompositionAgglomeration/decompositionMethods/lnInclude \
|
||||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude
|
-I$(LIB_SRC)/lagrangian/basic/lnInclude
|
||||||
|
|
||||||
LIB_LIBS = \
|
LIB_LIBS = \
|
||||||
-ltriSurface \
|
-ltriSurface \
|
||||||
|
-ldecompositionMethods \
|
||||||
-llagrangian
|
-llagrangian
|
||||||
|
|||||||
@ -31,38 +31,56 @@ License
|
|||||||
#include "triangleFuncs.H"
|
#include "triangleFuncs.H"
|
||||||
#include "matchPoints.H"
|
#include "matchPoints.H"
|
||||||
#include "globalIndex.H"
|
#include "globalIndex.H"
|
||||||
#include "PackedBoolList.H"
|
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
|
|
||||||
|
#include "IFstream.H"
|
||||||
|
#include "decompositionMethod.H"
|
||||||
|
#include "vectorList.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
defineTypeNameAndDebug(distributedTriSurfaceMesh, 0);
|
|
||||||
addToRunTimeSelectionTable
|
|
||||||
(
|
|
||||||
searchableSurface,
|
|
||||||
distributedTriSurfaceMesh,
|
|
||||||
dict
|
|
||||||
);
|
|
||||||
|
|
||||||
scalar distributedTriSurfaceMesh::mergeDist_ = SMALL;
|
defineTypeNameAndDebug(distributedTriSurfaceMesh, 0);
|
||||||
|
addToRunTimeSelectionTable(searchableSurface, distributedTriSurfaceMesh, dict);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
const char*
|
||||||
|
Foam::NamedEnum<Foam::distributedTriSurfaceMesh::distributionType, 3>::names[] =
|
||||||
|
{
|
||||||
|
"follow",
|
||||||
|
"independent",
|
||||||
|
"frozen"
|
||||||
|
};
|
||||||
|
|
||||||
|
const Foam::NamedEnum<Foam::distributedTriSurfaceMesh::distributionType, 3>
|
||||||
|
Foam::distributedTriSurfaceMesh::distributionTypeNames_;
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
// Read my additional data from the dictionary
|
// Read my additional data from the dictionary
|
||||||
bool Foam::distributedTriSurfaceMesh::read()
|
bool Foam::distributedTriSurfaceMesh::read()
|
||||||
{
|
{
|
||||||
// Get bb of all domains
|
// Get bb of all domains.
|
||||||
procBb_.setSize(Pstream::nProcs());
|
procBb_.setSize(Pstream::nProcs());
|
||||||
|
|
||||||
procBb_[Pstream::myProcNo()] = List<treeBoundBox>(dict_.lookup("bounds"));
|
procBb_[Pstream::myProcNo()] = List<treeBoundBox>(dict_.lookup("bounds"));
|
||||||
Pstream::gatherList(procBb_);
|
Pstream::gatherList(procBb_);
|
||||||
Pstream::scatterList(procBb_);
|
Pstream::scatterList(procBb_);
|
||||||
|
|
||||||
|
// Distribution type
|
||||||
|
distType_ = distributionTypeNames_.read(dict_.lookup("distributionType"));
|
||||||
|
|
||||||
|
if (dict_.found("mergeDistance"))
|
||||||
|
{
|
||||||
|
dict_.lookup("mergeDistance") >> mergeDist_;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +104,69 @@ bool Foam::distributedTriSurfaceMesh::isLocal
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::distributedTriSurfaceMesh::splitSegment
|
//void Foam::distributedTriSurfaceMesh::splitSegment
|
||||||
|
//(
|
||||||
|
// const label segmentI,
|
||||||
|
// const point& start,
|
||||||
|
// const point& end,
|
||||||
|
// const treeBoundBox& bb,
|
||||||
|
//
|
||||||
|
// DynamicList<segment>& allSegments,
|
||||||
|
// DynamicList<label>& allSegmentMap,
|
||||||
|
// DynamicList<label> sendMap
|
||||||
|
//) const
|
||||||
|
//{
|
||||||
|
// // Work points
|
||||||
|
// point clipPt0, clipPt1;
|
||||||
|
//
|
||||||
|
// if (bb.contains(start))
|
||||||
|
// {
|
||||||
|
// // start within, trim end to bb
|
||||||
|
// bool clipped = bb.intersects(end, start, clipPt0);
|
||||||
|
//
|
||||||
|
// if (clipped)
|
||||||
|
// {
|
||||||
|
// // segment from start to clippedStart passes
|
||||||
|
// // through proc.
|
||||||
|
// sendMap[procI].append(allSegments.size());
|
||||||
|
// allSegmentMap.append(segmentI);
|
||||||
|
// allSegments.append(segment(start, clipPt0));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else if (bb.contains(end))
|
||||||
|
// {
|
||||||
|
// // end within, trim start to bb
|
||||||
|
// bool clipped = bb.intersects(start, end, clipPt0);
|
||||||
|
//
|
||||||
|
// if (clipped)
|
||||||
|
// {
|
||||||
|
// sendMap[procI].append(allSegments.size());
|
||||||
|
// allSegmentMap.append(segmentI);
|
||||||
|
// allSegments.append(segment(clipPt0, end));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// // trim both
|
||||||
|
// bool clippedStart = bb.intersects(start, end, clipPt0);
|
||||||
|
//
|
||||||
|
// if (clippedStart)
|
||||||
|
// {
|
||||||
|
// bool clippedEnd = bb.intersects(end, clipPt0, clipPt1);
|
||||||
|
//
|
||||||
|
// if (clippedEnd)
|
||||||
|
// {
|
||||||
|
// // middle part of segment passes through proc.
|
||||||
|
// sendMap[procI].append(allSegments.size());
|
||||||
|
// allSegmentMap.append(segmentI);
|
||||||
|
// allSegments.append(segment(clipPt0, clipPt1));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::distributedTriSurfaceMesh::distributeSegment
|
||||||
(
|
(
|
||||||
const label segmentI,
|
const label segmentI,
|
||||||
const point& start,
|
const point& start,
|
||||||
@ -98,7 +178,7 @@ void Foam::distributedTriSurfaceMesh::splitSegment
|
|||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
// Work points
|
// Work points
|
||||||
point clipPt0, clipPt1;
|
point clipPt;
|
||||||
|
|
||||||
|
|
||||||
// 1. Fully local already handled outside. Note: retest is cheap.
|
// 1. Fully local already handled outside. Note: retest is cheap.
|
||||||
@ -108,9 +188,9 @@ void Foam::distributedTriSurfaceMesh::splitSegment
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 2. Check if fully inside other processor. Rare occurrence
|
// 2. If fully inside one other processor, then only need to send
|
||||||
|
// to that one processor even if it intersects another. Rare occurrence
|
||||||
// but cheap to test.
|
// but cheap to test.
|
||||||
|
|
||||||
forAll(procBb_, procI)
|
forAll(procBb_, procI)
|
||||||
{
|
{
|
||||||
if (procI != Pstream::myProcNo())
|
if (procI != Pstream::myProcNo())
|
||||||
@ -119,8 +199,6 @@ void Foam::distributedTriSurfaceMesh::splitSegment
|
|||||||
|
|
||||||
if (isLocal(bbs, start, end))
|
if (isLocal(bbs, start, end))
|
||||||
{
|
{
|
||||||
//Pout<< " Completely remote segment:"
|
|
||||||
// << start << end << " on proc:" << procI << endl;
|
|
||||||
sendMap[procI].append(allSegments.size());
|
sendMap[procI].append(allSegments.size());
|
||||||
allSegmentMap.append(segmentI);
|
allSegmentMap.append(segmentI);
|
||||||
allSegments.append(segment(start, end));
|
allSegments.append(segment(start, end));
|
||||||
@ -130,7 +208,8 @@ void Foam::distributedTriSurfaceMesh::splitSegment
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 3. Not contained in single processor. Clip against proc bbs.
|
// 3. If not contained in single processor send to all intersecting
|
||||||
|
// processors.
|
||||||
forAll(procBb_, procI)
|
forAll(procBb_, procI)
|
||||||
{
|
{
|
||||||
const List<treeBoundBox>& bbs = procBb_[procI];
|
const List<treeBoundBox>& bbs = procBb_[procI];
|
||||||
@ -139,67 +218,37 @@ void Foam::distributedTriSurfaceMesh::splitSegment
|
|||||||
{
|
{
|
||||||
const treeBoundBox& bb = bbs[bbI];
|
const treeBoundBox& bb = bbs[bbI];
|
||||||
|
|
||||||
if (bb.contains(start))
|
// Scheme a: any processor that intersects the segment gets
|
||||||
|
// the segment.
|
||||||
|
|
||||||
|
if (bb.intersects(start, end, clipPt))
|
||||||
{
|
{
|
||||||
// start within, trim end to bb
|
sendMap[procI].append(allSegments.size());
|
||||||
bool clipped = bb.intersects(end, start, clipPt0);
|
allSegmentMap.append(segmentI);
|
||||||
|
allSegments.append(segment(start, end));
|
||||||
if (clipped)
|
|
||||||
{
|
|
||||||
//Pout<< " Start of segment:"
|
|
||||||
// << start << end << " clips proc:" << procI
|
|
||||||
// << " at " << clipPt0 << endl;
|
|
||||||
// segment from start to clippedStart passes
|
|
||||||
// through proc.
|
|
||||||
sendMap[procI].append(allSegments.size());
|
|
||||||
allSegmentMap.append(segmentI);
|
|
||||||
allSegments.append(segment(start, clipPt0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (bb.contains(end))
|
|
||||||
{
|
|
||||||
// end within, trim start to bb
|
|
||||||
bool clipped = bb.intersects(start, end, clipPt0);
|
|
||||||
|
|
||||||
if (clipped)
|
// Alternative: any processor only gets clipped bit of
|
||||||
{
|
// segment. This gives small problems with additional
|
||||||
//Pout<< " End of segment:"
|
// truncation errors.
|
||||||
// << start << end << " clips proc:" << procI
|
//splitSegment
|
||||||
// << " at " << clipPt0 << endl;
|
//(
|
||||||
sendMap[procI].append(allSegments.size());
|
// segmentI,
|
||||||
allSegmentMap.append(segmentI);
|
// start,
|
||||||
allSegments.append(segment(clipPt0, end));
|
// end,
|
||||||
}
|
// bb,
|
||||||
}
|
//
|
||||||
else
|
// allSegments,
|
||||||
{
|
// allSegmentMap,
|
||||||
// trim both
|
// sendMap[procI]
|
||||||
bool clippedStart = bb.intersects(start, end, clipPt0);
|
//);
|
||||||
|
|
||||||
if (clippedStart)
|
|
||||||
{
|
|
||||||
bool clippedEnd = bb.intersects(end, clipPt0, clipPt1);
|
|
||||||
|
|
||||||
if (clippedEnd)
|
|
||||||
{
|
|
||||||
//Pout<< " Middle of segment:"
|
|
||||||
// << start << end << " clips proc:" << procI
|
|
||||||
// << " at " << clipPt0 << clipPt1 << endl;
|
|
||||||
// middle part of segment passes through
|
|
||||||
// proc.
|
|
||||||
sendMap[procI].append(allSegments.size());
|
|
||||||
allSegmentMap.append(segmentI);
|
|
||||||
allSegments.append(segment(clipPt0, clipPt1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::autoPtr<Foam::mapDistribute>
|
Foam::autoPtr<Foam::mapDistribute>
|
||||||
Foam::distributedTriSurfaceMesh::constructSegments
|
Foam::distributedTriSurfaceMesh::distributeSegments
|
||||||
(
|
(
|
||||||
const pointField& start,
|
const pointField& start,
|
||||||
const pointField& end,
|
const pointField& end,
|
||||||
@ -227,7 +276,7 @@ Foam::distributedTriSurfaceMesh::constructSegments
|
|||||||
|
|
||||||
forAll(start, segmentI)
|
forAll(start, segmentI)
|
||||||
{
|
{
|
||||||
splitSegment
|
distributeSegment
|
||||||
(
|
(
|
||||||
segmentI,
|
segmentI,
|
||||||
start[segmentI],
|
start[segmentI],
|
||||||
@ -243,11 +292,12 @@ Foam::distributedTriSurfaceMesh::constructSegments
|
|||||||
sendMap.setSize(Pstream::nProcs());
|
sendMap.setSize(Pstream::nProcs());
|
||||||
forAll(sendMap, procI)
|
forAll(sendMap, procI)
|
||||||
{
|
{
|
||||||
|
dynSendMap[procI].shrink();
|
||||||
sendMap[procI].transfer(dynSendMap[procI]);
|
sendMap[procI].transfer(dynSendMap[procI]);
|
||||||
}
|
}
|
||||||
|
|
||||||
allSegments.transfer(dynAllSegments);
|
allSegments.transfer(dynAllSegments.shrink());
|
||||||
allSegmentMap.transfer(dynAllSegmentMap);
|
allSegmentMap.transfer(dynAllSegmentMap.shrink());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -371,7 +421,7 @@ void Foam::distributedTriSurfaceMesh::findLine
|
|||||||
|
|
||||||
const autoPtr<mapDistribute> mapPtr
|
const autoPtr<mapDistribute> mapPtr
|
||||||
(
|
(
|
||||||
constructSegments
|
distributeSegments
|
||||||
(
|
(
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
@ -707,12 +757,13 @@ Foam::distributedTriSurfaceMesh::calcLocalQueries
|
|||||||
sendMap.setSize(Pstream::nProcs());
|
sendMap.setSize(Pstream::nProcs());
|
||||||
forAll(sendMap, procI)
|
forAll(sendMap, procI)
|
||||||
{
|
{
|
||||||
|
dynSendMap[procI].shrink();
|
||||||
sendMap[procI].transfer(dynSendMap[procI]);
|
sendMap[procI].transfer(dynSendMap[procI]);
|
||||||
}
|
}
|
||||||
|
|
||||||
allCentres.transfer(dynAllCentres);
|
allCentres.transfer(dynAllCentres.shrink());
|
||||||
allRadiusSqr.transfer(dynAllRadiusSqr);
|
allRadiusSqr.transfer(dynAllRadiusSqr.shrink());
|
||||||
allSegmentMap.transfer(dynAllSegmentMap);
|
allSegmentMap.transfer(dynAllSegmentMap.shrink());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -766,6 +817,102 @@ Foam::distributedTriSurfaceMesh::calcLocalQueries
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Find bounding boxes that guarantee a more or less uniform distribution
|
||||||
|
// of triangles. Decomposition in here is only used to get the bounding
|
||||||
|
// boxes, actual decomposition is done later on.
|
||||||
|
// Returns a per processor a list of bounding boxes that most accurately
|
||||||
|
// describe the shape. For now just a single bounding box per processor but
|
||||||
|
// optimisation might be to determine a better fitting shape.
|
||||||
|
Foam::List<Foam::List<Foam::treeBoundBox> >
|
||||||
|
Foam::distributedTriSurfaceMesh::independentlyDistributedBbs
|
||||||
|
(
|
||||||
|
const triSurface& s
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!decomposer_.valid())
|
||||||
|
{
|
||||||
|
// Use current decomposer.
|
||||||
|
// Note: or always use hierarchical?
|
||||||
|
IOdictionary decomposeDict
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"decomposeParDict",
|
||||||
|
searchableSurface::time().system(),
|
||||||
|
searchableSurface::time(),
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
);
|
||||||
|
decomposer_ = decompositionMethod::New(decomposeDict);
|
||||||
|
|
||||||
|
if (!decomposer_().parallelAware())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"distributedTriSurfaceMesh::independentlyDistributedBbs"
|
||||||
|
"(const triSurface&)"
|
||||||
|
) << "The decomposition method " << decomposer_().typeName
|
||||||
|
<< " does not decompose in parallel."
|
||||||
|
<< " Please choose one that does." << exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do decomposition according to triangle centre
|
||||||
|
pointField triCentres(s.size());
|
||||||
|
forAll (s, triI)
|
||||||
|
{
|
||||||
|
triCentres[triI] = s[triI].centre(s.points());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do the actual decomposition
|
||||||
|
labelList distribution(decomposer_->decompose(triCentres));
|
||||||
|
|
||||||
|
// Find bounding box for all triangles on new distribution.
|
||||||
|
|
||||||
|
// Initialise to inverted box (VGREAT, -VGREAT)
|
||||||
|
List<List<treeBoundBox> > bbs(Pstream::nProcs());
|
||||||
|
forAll(bbs, procI)
|
||||||
|
{
|
||||||
|
bbs[procI].setSize(1);
|
||||||
|
//bbs[procI][0] = boundBox::invertedBox;
|
||||||
|
bbs[procI][0].min() = point( VGREAT, VGREAT, VGREAT);
|
||||||
|
bbs[procI][0].max() = point(-VGREAT, -VGREAT, -VGREAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll (s, triI)
|
||||||
|
{
|
||||||
|
point& bbMin = bbs[distribution[triI]][0].min();
|
||||||
|
point& bbMax = bbs[distribution[triI]][0].max();
|
||||||
|
|
||||||
|
const labelledTri& f = s[triI];
|
||||||
|
const point& p0 = s.points()[f[0]];
|
||||||
|
const point& p1 = s.points()[f[1]];
|
||||||
|
const point& p2 = s.points()[f[2]];
|
||||||
|
|
||||||
|
bbMin = min(bbMin, p0);
|
||||||
|
bbMin = min(bbMin, p1);
|
||||||
|
bbMin = min(bbMin, p2);
|
||||||
|
|
||||||
|
bbMax = max(bbMax, p0);
|
||||||
|
bbMax = max(bbMax, p1);
|
||||||
|
bbMax = max(bbMax, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now combine for all processors and convert to correct format.
|
||||||
|
forAll(bbs, procI)
|
||||||
|
{
|
||||||
|
forAll(bbs[procI], i)
|
||||||
|
{
|
||||||
|
reduce(bbs[procI][i].min(), minOp<point>());
|
||||||
|
reduce(bbs[procI][i].max(), maxOp<point>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::distributedTriSurfaceMesh::calcBounds
|
void Foam::distributedTriSurfaceMesh::calcBounds
|
||||||
(
|
(
|
||||||
boundBox& bb,
|
boundBox& bb,
|
||||||
@ -775,10 +922,12 @@ void Foam::distributedTriSurfaceMesh::calcBounds
|
|||||||
// Unfortunately nPoints constructs meshPoints() so do compact version
|
// Unfortunately nPoints constructs meshPoints() so do compact version
|
||||||
// ourselves
|
// ourselves
|
||||||
|
|
||||||
PackedBoolList pointIsUsed(points().size());
|
PackedList<1> pointIsUsed(points().size());
|
||||||
|
pointIsUsed = 0U;
|
||||||
|
|
||||||
nPoints = 0;
|
nPoints = 0;
|
||||||
bb = boundBox::invertedBox;
|
bb.min() = point(VGREAT, VGREAT, VGREAT);
|
||||||
|
bb.max() = point(-VGREAT, -VGREAT, -VGREAT);
|
||||||
|
|
||||||
const triSurface& s = static_cast<const triSurface&>(*this);
|
const triSurface& s = static_cast<const triSurface&>(*this);
|
||||||
|
|
||||||
@ -1198,17 +1347,30 @@ Foam::distributedTriSurfaceMesh::distributedTriSurfaceMesh
|
|||||||
Foam::distributedTriSurfaceMesh::distributedTriSurfaceMesh(const IOobject& io)
|
Foam::distributedTriSurfaceMesh::distributedTriSurfaceMesh(const IOobject& io)
|
||||||
:
|
:
|
||||||
triSurfaceMesh(io),
|
triSurfaceMesh(io),
|
||||||
|
// triSurfaceMesh
|
||||||
|
// (
|
||||||
|
// IOobject
|
||||||
|
// (
|
||||||
|
// io.name(),
|
||||||
|
// io.db().time().findInstanceDir(io.local()),
|
||||||
|
// io.local(),
|
||||||
|
// io.db(),
|
||||||
|
// io.readOpt(),
|
||||||
|
// io.writeOpt(),
|
||||||
|
// io.registerObject()
|
||||||
|
// )
|
||||||
|
// ),
|
||||||
dict_
|
dict_
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
io.name() + "Dict",
|
searchableSurface::name() + "Dict",
|
||||||
io.instance(),
|
searchableSurface::instance(),
|
||||||
io.local(),
|
searchableSurface::local(),
|
||||||
io.db(),
|
searchableSurface::db(),
|
||||||
io.readOpt(),
|
searchableSurface::readOpt(),
|
||||||
io.writeOpt(),
|
searchableSurface::writeOpt(),
|
||||||
io.registerObject()
|
searchableSurface::registerObject()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -1223,17 +1385,31 @@ Foam::distributedTriSurfaceMesh::distributedTriSurfaceMesh
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
triSurfaceMesh(io, dict),
|
triSurfaceMesh(io, dict),
|
||||||
|
// triSurfaceMesh
|
||||||
|
// (
|
||||||
|
// IOobject
|
||||||
|
// (
|
||||||
|
// io.name(),
|
||||||
|
// io.db().time().findInstanceDir(io.local()),
|
||||||
|
// io.local(),
|
||||||
|
// io.db(),
|
||||||
|
// io.readOpt(),
|
||||||
|
// io.writeOpt(),
|
||||||
|
// io.registerObject()
|
||||||
|
// ),
|
||||||
|
// dict
|
||||||
|
// ),
|
||||||
dict_
|
dict_
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
io.name() + "Dict",
|
searchableSurface::name() + "Dict",
|
||||||
io.instance(),
|
searchableSurface::instance(),
|
||||||
io.local(),
|
searchableSurface::local(),
|
||||||
io.db(),
|
searchableSurface::db(),
|
||||||
io.readOpt(),
|
searchableSurface::readOpt(),
|
||||||
io.writeOpt(),
|
searchableSurface::writeOpt(),
|
||||||
io.registerObject()
|
searchableSurface::registerObject()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -1260,7 +1436,7 @@ void Foam::distributedTriSurfaceMesh::clearOut()
|
|||||||
|
|
||||||
const Foam::globalIndex& Foam::distributedTriSurfaceMesh::globalTris() const
|
const Foam::globalIndex& Foam::distributedTriSurfaceMesh::globalTris() const
|
||||||
{
|
{
|
||||||
if (globalTris_.empty())
|
if (!globalTris_.valid())
|
||||||
{
|
{
|
||||||
globalTris_.reset(new globalIndex(triSurface::size()));
|
globalTris_.reset(new globalIndex(triSurface::size()));
|
||||||
}
|
}
|
||||||
@ -1855,6 +2031,18 @@ Foam::triSurface Foam::distributedTriSurfaceMesh::overlappingSurface
|
|||||||
// Determine what triangles to keep.
|
// Determine what triangles to keep.
|
||||||
boolList includedFace(s.size(), false);
|
boolList includedFace(s.size(), false);
|
||||||
|
|
||||||
|
// Create a slightly larger bounding box.
|
||||||
|
List<treeBoundBox> bbsX(bbs.size());
|
||||||
|
const scalar eps = 1.0e-4;
|
||||||
|
forAll(bbs, i)
|
||||||
|
{
|
||||||
|
const point mid = 0.5*(bbs[i].min() + bbs[i].max());
|
||||||
|
const vector halfSpan = (1.0+eps)*(bbs[i].max() - mid);
|
||||||
|
|
||||||
|
bbsX[i].min() = mid - halfSpan;
|
||||||
|
bbsX[i].max() = mid + halfSpan;
|
||||||
|
}
|
||||||
|
|
||||||
forAll(s, triI)
|
forAll(s, triI)
|
||||||
{
|
{
|
||||||
const labelledTri& f = s[triI];
|
const labelledTri& f = s[triI];
|
||||||
@ -1862,7 +2050,7 @@ Foam::triSurface Foam::distributedTriSurfaceMesh::overlappingSurface
|
|||||||
const point& p1 = s.points()[f[1]];
|
const point& p1 = s.points()[f[1]];
|
||||||
const point& p2 = s.points()[f[2]];
|
const point& p2 = s.points()[f[2]];
|
||||||
|
|
||||||
if (overlaps(bbs, p0, p1, p2))
|
if (overlaps(bbsX, p0, p1, p2))
|
||||||
{
|
{
|
||||||
includedFace[triI] = true;
|
includedFace[triI] = true;
|
||||||
}
|
}
|
||||||
@ -1880,17 +2068,37 @@ void Foam::distributedTriSurfaceMesh::distribute
|
|||||||
autoPtr<mapDistribute>& pointMap
|
autoPtr<mapDistribute>& pointMap
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Get bb of all domains
|
// Get bbs of all domains
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
{
|
{
|
||||||
List<List<treeBoundBox> > newProcBb(Pstream::nProcs());
|
List<List<treeBoundBox> > newProcBb(Pstream::nProcs());
|
||||||
newProcBb[Pstream::myProcNo()].setSize(bbs.size());
|
|
||||||
forAll(bbs, i)
|
|
||||||
{
|
|
||||||
newProcBb[Pstream::myProcNo()][i] = bbs[i];
|
|
||||||
}
|
|
||||||
Pstream::gatherList(newProcBb);
|
|
||||||
Pstream::scatterList(newProcBb);
|
|
||||||
|
|
||||||
|
switch(distType_)
|
||||||
|
{
|
||||||
|
case FOLLOW:
|
||||||
|
newProcBb[Pstream::myProcNo()].setSize(bbs.size());
|
||||||
|
forAll(bbs, i)
|
||||||
|
{
|
||||||
|
newProcBb[Pstream::myProcNo()][i] = bbs[i];
|
||||||
|
}
|
||||||
|
Pstream::gatherList(newProcBb);
|
||||||
|
Pstream::scatterList(newProcBb);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INDEPENDENT:
|
||||||
|
newProcBb = independentlyDistributedBbs(*this);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FROZEN:
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FatalErrorIn("distributedTriSurfaceMesh::distribute(..)")
|
||||||
|
<< "Unsupported distribution type." << exit(FatalError);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
//if (debug)
|
//if (debug)
|
||||||
//{
|
//{
|
||||||
@ -1931,6 +2139,9 @@ void Foam::distributedTriSurfaceMesh::distribute
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Use procBbs to determine which faces go where
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
labelListList faceSendMap(Pstream::nProcs());
|
labelListList faceSendMap(Pstream::nProcs());
|
||||||
labelListList pointSendMap(Pstream::nProcs());
|
labelListList pointSendMap(Pstream::nProcs());
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,20 @@ Class
|
|||||||
Foam::distributedTriSurfaceMesh
|
Foam::distributedTriSurfaceMesh
|
||||||
|
|
||||||
Description
|
Description
|
||||||
IOoject and searching on triSurface
|
IOoject and searching on distributed triSurface. All processor hold
|
||||||
|
(possibly overlapping) part of the overall surface. All queries are
|
||||||
|
distributed to the processor that can answer it and the result sent back.
|
||||||
|
|
||||||
|
Can work in three modes:
|
||||||
|
- follow : makes sure each processor has all the triangles inside the
|
||||||
|
externally provided bounding box (usually the mesh bounding box).
|
||||||
|
Guarantees minimum amount of communication since mesh-local queries
|
||||||
|
should be answerable without any comms.
|
||||||
|
- independent : surface is decomposed according to the triangle centres
|
||||||
|
so the decomposition might be radically different from the mesh
|
||||||
|
decomposition. Guarantees best memory balance but at the expense of
|
||||||
|
more communication.
|
||||||
|
- frozen : no change
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
distributedTriSurfaceMesh.C
|
distributedTriSurfaceMesh.C
|
||||||
@ -47,6 +60,7 @@ namespace Foam
|
|||||||
{
|
{
|
||||||
|
|
||||||
class mapDistribute;
|
class mapDistribute;
|
||||||
|
class decompositionMethod;
|
||||||
|
|
||||||
// Typedefs
|
// Typedefs
|
||||||
typedef Pair<point> segment;
|
typedef Pair<point> segment;
|
||||||
@ -62,12 +76,26 @@ class distributedTriSurfaceMesh
|
|||||||
:
|
:
|
||||||
public triSurfaceMesh
|
public triSurfaceMesh
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
|
|
||||||
// Static data
|
// Static data
|
||||||
|
|
||||||
|
enum distributionType
|
||||||
|
{
|
||||||
|
FOLLOW = 0,
|
||||||
|
INDEPENDENT = 1,
|
||||||
|
FROZEN = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
static const NamedEnum<distributionType, 3> distributionTypeNames_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
//- Merging distance
|
//- Merging distance
|
||||||
static scalar mergeDist_;
|
scalar mergeDist_;
|
||||||
|
|
||||||
|
//- Decomposition used when independently decomposing surface.
|
||||||
|
autoPtr<decompositionMethod> decomposer_;
|
||||||
|
|
||||||
|
|
||||||
// Private member data
|
// Private member data
|
||||||
@ -81,6 +109,9 @@ private:
|
|||||||
//- Global triangle numbering
|
//- Global triangle numbering
|
||||||
mutable autoPtr<globalIndex> globalTris_;
|
mutable autoPtr<globalIndex> globalTris_;
|
||||||
|
|
||||||
|
//- The distribution type.
|
||||||
|
distributionType distType_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
@ -100,8 +131,22 @@ private:
|
|||||||
);
|
);
|
||||||
|
|
||||||
//- Split segment into subsegments overlapping the processor
|
//- Split segment into subsegments overlapping the processor
|
||||||
|
// bounding box.
|
||||||
|
//void Foam::distributedTriSurfaceMesh::splitSegment
|
||||||
|
//(
|
||||||
|
// const label segmentI,
|
||||||
|
// const point& start,
|
||||||
|
// const point& end,
|
||||||
|
// const treeBoundBox& bb,
|
||||||
|
//
|
||||||
|
// DynamicList<segment>& allSegments,
|
||||||
|
// DynamicList<label>& allSegmentMap,
|
||||||
|
// DynamicList<label> sendMap
|
||||||
|
//) const
|
||||||
|
|
||||||
|
//- Distribute segments into overlapping processor
|
||||||
// bounding boxes. Sort per processor.
|
// bounding boxes. Sort per processor.
|
||||||
void splitSegment
|
void distributeSegment
|
||||||
(
|
(
|
||||||
const label,
|
const label,
|
||||||
const point& start,
|
const point& start,
|
||||||
@ -114,7 +159,7 @@ private:
|
|||||||
|
|
||||||
//- Divide edges into local and remote segments. Construct map to
|
//- Divide edges into local and remote segments. Construct map to
|
||||||
// distribute and collect data.
|
// distribute and collect data.
|
||||||
autoPtr<mapDistribute> constructSegments
|
autoPtr<mapDistribute> distributeSegments
|
||||||
(
|
(
|
||||||
const pointField& start,
|
const pointField& start,
|
||||||
const pointField& end,
|
const pointField& end,
|
||||||
@ -167,6 +212,12 @@ private:
|
|||||||
|
|
||||||
// Surface redistribution
|
// Surface redistribution
|
||||||
|
|
||||||
|
//- Finds new bounds based on an indepedent decomposition.
|
||||||
|
List<List<treeBoundBox> > independentlyDistributedBbs
|
||||||
|
(
|
||||||
|
const triSurface&
|
||||||
|
);
|
||||||
|
|
||||||
//- Calculate surface bounding box
|
//- Calculate surface bounding box
|
||||||
void calcBounds(boundBox& bb, label& nPoints) const;
|
void calcBounds(boundBox& bb, label& nPoints) const;
|
||||||
|
|
||||||
@ -287,32 +338,6 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Return merge distance
|
|
||||||
static scalar mergeDist()
|
|
||||||
{
|
|
||||||
return mergeDist_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Set the merge distance, returning the previous value
|
|
||||||
static scalar setMergeDist(const scalar t)
|
|
||||||
{
|
|
||||||
if (t < -VSMALL)
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"scalar distributedTriSurfaceMesh::setMergeDist"
|
|
||||||
"(const scalar t)"
|
|
||||||
) << "Negative merge distance tolerance. This is not allowed."
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
scalar oldTol = mergeDist_;
|
|
||||||
mergeDist_ = t;
|
|
||||||
|
|
||||||
return oldTol;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//- Triangle indexing (demand driven)
|
//- Triangle indexing (demand driven)
|
||||||
const globalIndex& globalTris() const;
|
const globalIndex& globalTris() const;
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,7 @@ License
|
|||||||
#include "searchableSurfaces.H"
|
#include "searchableSurfaces.H"
|
||||||
#include "searchableSurfacesQueries.H"
|
#include "searchableSurfacesQueries.H"
|
||||||
#include "ListOps.H"
|
#include "ListOps.H"
|
||||||
|
#include "Time.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -186,6 +187,14 @@ Foam::searchableSurfaces::searchableSurfaces
|
|||||||
// their object name. Maybe have stlTriSurfaceMesh which appends .stl
|
// their object name. Maybe have stlTriSurfaceMesh which appends .stl
|
||||||
// when reading/writing?
|
// when reading/writing?
|
||||||
namedIO().rename(key); // names_[surfI]
|
namedIO().rename(key); // names_[surfI]
|
||||||
|
if (namedIO().local() != word::null)
|
||||||
|
{
|
||||||
|
namedIO().instance() = namedIO().time().findInstance
|
||||||
|
(
|
||||||
|
namedIO().local(),
|
||||||
|
namedIO().name()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Create and hook surface
|
// Create and hook surface
|
||||||
set
|
set
|
||||||
|
|||||||
Reference in New Issue
Block a user