Merge branch 'master' of ssh://hunt/home/hunt2/OpenFOAM/OpenFOAM-dev

This commit is contained in:
henry
2008-09-03 08:38:23 +01:00
40 changed files with 505 additions and 163 deletions

View File

@ -504,7 +504,7 @@ int main(int argc, char *argv[])
!bbsTargetSet[procITarget] !bbsTargetSet[procITarget]
|| ( || (
bbsTargetSet[procITarget] bbsTargetSet[procITarget]
&& bbsTarget[procITarget].intersects(bbSource) && bbsTarget[procITarget].overlaps(bbSource)
) )
) )
{ {
@ -533,7 +533,7 @@ int main(int argc, char *argv[])
bbsTarget[procITarget] = meshTarget.bounds(); bbsTarget[procITarget] = meshTarget.bounds();
bbsTargetSet[procITarget] = true; bbsTargetSet[procITarget] = true;
if (bbsTarget[procITarget].intersects(bbSource)) if (bbsTarget[procITarget].overlaps(bbSource))
{ {
if (consistent) if (consistent)
{ {

View File

@ -86,28 +86,7 @@ void Foam::SortableList<Type>::sort()
indices_[i] = i; indices_[i] = i;
} }
Foam::sort(indices_, less(*this)); //Foam::sort(indices_, less(*this));
List<Type> tmpValues(this->size());
forAll(indices_, i)
{
tmpValues[i] = this->operator[](indices_[i]);
}
List<Type>::transfer(tmpValues);
}
template <class Type>
void Foam::SortableList<Type>::stableSort()
{
forAll(indices_, i)
{
indices_[i] = i;
}
Foam::stableSort(indices_, less(*this)); Foam::stableSort(indices_, less(*this));
List<Type> tmpValues(this->size()); List<Type> tmpValues(this->size());

View File

@ -109,12 +109,9 @@ public:
//- Size the list. If grow can cause undefined indices (until next sort) //- Size the list. If grow can cause undefined indices (until next sort)
void setSize(const label); void setSize(const label);
//- Sort the list (if changed after construction time) //- (stable) sort the list (if changed after construction time)
void sort(); void sort();
//- Sort the list (if changed after construction time)
void stableSort();
// Member Operators // Member Operators

View File

@ -118,7 +118,7 @@ public:
// Query // Query
//- Intersects other boundingbox? //- Intersects other boundingbox?
bool intersects(const boundBox& bb) const bool overlaps(const boundBox& bb) const
{ {
if if
( (

View File

@ -31,7 +31,11 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::mapDistribute::calcSchedule() const Foam::List<Foam::labelPair> Foam::mapDistribute::schedule
(
const labelListList& subMap,
const labelListList& constructMap
)
{ {
// Communications: send and receive processor // Communications: send and receive processor
List<labelPair> allComms; List<labelPair> allComms;
@ -40,16 +44,16 @@ void Foam::mapDistribute::calcSchedule() const
HashSet<labelPair, labelPair::Hash<> > commsSet(Pstream::nProcs()); HashSet<labelPair, labelPair::Hash<> > commsSet(Pstream::nProcs());
// Find what communication is required // Find what communication is required
forAll(subMap_, procI) forAll(subMap, procI)
{ {
if (procI != Pstream::myProcNo()) if (procI != Pstream::myProcNo())
{ {
if (subMap_[procI].size() > 0) if (subMap[procI].size() > 0)
{ {
// I need to send to procI // I need to send to procI
commsSet.insert(labelPair(Pstream::myProcNo(), procI)); commsSet.insert(labelPair(Pstream::myProcNo(), procI));
} }
if (constructMap_[procI].size() > 0) if (constructMap[procI].size() > 0)
{ {
// I need to receive from procI // I need to receive from procI
commsSet.insert(labelPair(procI, Pstream::myProcNo())); commsSet.insert(labelPair(procI, Pstream::myProcNo()));
@ -120,13 +124,7 @@ void Foam::mapDistribute::calcSchedule() const
); );
// Processors involved in my schedule // Processors involved in my schedule
schedulePtr_.reset return IndirectList<labelPair>(allComms, mySchedule);
(
new List<labelPair>
(
IndirectList<labelPair>(allComms, mySchedule)
)
);
//if (debug) //if (debug)
@ -152,6 +150,22 @@ void Foam::mapDistribute::calcSchedule() const
} }
const Foam::List<Foam::labelPair>& Foam::mapDistribute::schedule() const
{
if (!schedulePtr_.valid())
{
schedulePtr_.reset
(
new List<labelPair>
(
schedule(subMap_, constructMap_)
)
);
}
return schedulePtr_();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
//- Construct from components //- Construct from components
@ -257,13 +271,4 @@ Foam::mapDistribute::mapDistribute
} }
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
// ************************************************************************* // // ************************************************************************* //

View File

@ -36,6 +36,8 @@ Note:
Schedule is a list of processor pairs (one send, one receive. One of Schedule is a list of processor pairs (one send, one receive. One of
them will be myself) which forms a scheduled (i.e. non-buffered) exchange. them will be myself) which forms a scheduled (i.e. non-buffered) exchange.
See distribute on how to use it. See distribute on how to use it.
Note2: number of items send on one processor have to equal the number
of items received on the other processor.
SourceFiles SourceFiles
@ -80,8 +82,6 @@ class mapDistribute
// Private Member Functions // Private Member Functions
void calcSchedule() const;
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
mapDistribute(const mapDistribute&); mapDistribute(const mapDistribute&);
@ -142,15 +142,15 @@ public:
return constructMap_; return constructMap_;
} }
//- Calculate a schedule. See above.
static List<labelPair> schedule
(
const labelListList& subMap,
const labelListList& constructMap
);
//- Return a schedule. Demand driven. See above. //- Return a schedule. Demand driven. See above.
const List<labelPair>& schedule() const const List<labelPair>& schedule() const;
{
if (!schedulePtr_.valid())
{
calcSchedule();
}
return schedulePtr_();
}
// Other // Other

View File

@ -48,15 +48,28 @@ void Foam::mapDistribute::distribute
// Send sub field to neighbour // Send sub field to neighbour
for (label domain = 0; domain < Pstream::nProcs(); domain++) for (label domain = 0; domain < Pstream::nProcs(); domain++)
{ {
if (domain != Pstream::myProcNo()) const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size() > 0)
{ {
List<T> subField(map.size());
forAll(map, i)
{
subField[i] = field[map[i]];
}
OPstream toNbr(Pstream::blocking, domain); OPstream toNbr(Pstream::blocking, domain);
toNbr << IndirectList<T>(field, subMap[domain])(); toNbr << subField;
} }
} }
// Subset myself // Subset myself
List<T> subField(IndirectList<T>(field, subMap[Pstream::myProcNo()])); const labelList& mySubMap = subMap[Pstream::myProcNo()];
List<T> subField(mySubMap.size());
forAll(mySubMap, i)
{
subField[i] = field[mySubMap[i]];
}
// Receive sub field from myself (subField) // Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()]; const labelList& map = constructMap[Pstream::myProcNo()];
@ -71,7 +84,11 @@ void Foam::mapDistribute::distribute
// Receive sub field from neighbour // Receive sub field from neighbour
for (label domain = 0; domain < Pstream::nProcs(); domain++) for (label domain = 0; domain < Pstream::nProcs(); domain++)
{ {
if (domain != Pstream::myProcNo()) if
(
domain != Pstream::myProcNo()
&& constructMap[domain].size() > 0
)
{ {
IPstream fromNbr(Pstream::blocking, domain); IPstream fromNbr(Pstream::blocking, domain);
List<T> subField(fromNbr); List<T> subField(fromNbr);
@ -93,7 +110,13 @@ void Foam::mapDistribute::distribute
List<T> newField(constructSize); List<T> newField(constructSize);
// Subset myself // Subset myself
List<T> subField(IndirectList<T>(field, subMap[Pstream::myProcNo()])); const labelList& mySubMap = subMap[Pstream::myProcNo()];
List<T> subField(mySubMap.size());
forAll(mySubMap, i)
{
subField[i] = field[mySubMap[i]];
}
// Receive sub field from myself (subField) // Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()]; const labelList& map = constructMap[Pstream::myProcNo()];
@ -112,8 +135,16 @@ void Foam::mapDistribute::distribute
if (Pstream::myProcNo() == sendProc) if (Pstream::myProcNo() == sendProc)
{ {
// I am sender. Send to recvProc. // I am sender. Send to recvProc.
const labelList& map = subMap[recvProc];
List<T> subField(map.size());
forAll(map, i)
{
subField[i] = field[map[i]];
}
OPstream toNbr(Pstream::scheduled, recvProc); OPstream toNbr(Pstream::scheduled, recvProc);
toNbr << IndirectList<T>(field, subMap[recvProc])(); toNbr << subField;
} }
else else
{ {
@ -136,7 +167,13 @@ void Foam::mapDistribute::distribute
List<T> newField(constructSize); List<T> newField(constructSize);
// Subset myself // Subset myself
List<T> subField(IndirectList<T>(field, subMap[Pstream::myProcNo()])); const labelList& mySubMap = subMap[Pstream::myProcNo()];
List<T> subField(mySubMap.size());
forAll(mySubMap, i)
{
subField[i] = field[mySubMap[i]];
}
// Receive sub field from myself (subField) // Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()]; const labelList& map = constructMap[Pstream::myProcNo()];
@ -149,10 +186,19 @@ void Foam::mapDistribute::distribute
// Send sub field to neighbour // Send sub field to neighbour
for (label domain = 0; domain < Pstream::nProcs(); domain++) for (label domain = 0; domain < Pstream::nProcs(); domain++)
{ {
if (domain != Pstream::myProcNo()) const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size() > 0)
{ {
List<T> subField(map.size());
forAll(map, i)
{
subField[i] = field[map[i]];
}
OPstream toNbr(Pstream::nonBlocking, domain); OPstream toNbr(Pstream::nonBlocking, domain);
toNbr << IndirectList<T>(field, subMap[domain])(); toNbr << subField;
} }
} }
@ -160,13 +206,13 @@ void Foam::mapDistribute::distribute
// Receive sub field from neighbour // Receive sub field from neighbour
for (label domain = 0; domain < Pstream::nProcs(); domain++) for (label domain = 0; domain < Pstream::nProcs(); domain++)
{ {
if (domain != Pstream::myProcNo()) const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size() > 0)
{ {
IPstream fromNbr(Pstream::nonBlocking, domain); IPstream fromNbr(Pstream::nonBlocking, domain);
List<T> subField(fromNbr); List<T> subField(fromNbr);
const labelList& map = constructMap[domain];
forAll(map, i) forAll(map, i)
{ {
newField[map[i]] = subField[i]; newField[map[i]] = subField[i];

View File

@ -25,7 +25,6 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "coupledPolyPatch.H" #include "coupledPolyPatch.H"
#include "SortableList.H"
#include "ListOps.H" #include "ListOps.H"
#include "transform.H" #include "transform.H"
#include "OFstream.H" #include "OFstream.H"

View File

@ -68,6 +68,42 @@ PrimitivePatch<Face, FaceList, PointField, PointType>::PrimitivePatch
{} {}
// Construct from components
template
<
class Face,
template<class> class FaceList,
class PointField,
class PointType
>
PrimitivePatch<Face, FaceList, PointField, PointType>::PrimitivePatch
(
FaceList<Face>& faces,
Field<PointType>& points,
const bool reUse
)
:
FaceList<Face>(faces, reUse),
points_(points, reUse),
edgesPtr_(NULL),
nInternalEdges_(-1),
boundaryPointsPtr_(NULL),
faceFacesPtr_(NULL),
edgeFacesPtr_(NULL),
faceEdgesPtr_(NULL),
pointEdgesPtr_(NULL),
pointFacesPtr_(NULL),
localFacesPtr_(NULL),
meshPointsPtr_(NULL),
meshPointMapPtr_(NULL),
edgeLoopsPtr_(NULL),
localPointsPtr_(NULL),
localPointOrderPtr_(NULL),
faceNormalsPtr_(NULL),
pointNormalsPtr_(NULL)
{}
// Construct as copy // Construct as copy
template template
< <

View File

@ -235,6 +235,14 @@ public:
const Field<PointType>& points const Field<PointType>& points
); );
//- Construct from components, reuse storage
PrimitivePatch
(
FaceList<Face>& faces,
Field<PointType>& points,
const bool reUse
);
//- Construct as copy //- Construct as copy
PrimitivePatch PrimitivePatch
( (

View File

@ -467,7 +467,8 @@ const edgeList& primitiveMesh::edges() const
{ {
if (!edgesPtr_) if (!edgesPtr_)
{ {
calcEdges(true); //calcEdges(true);
calcEdges(false);
} }
return *edgesPtr_; return *edgesPtr_;
@ -477,10 +478,8 @@ const labelListList& primitiveMesh::pointEdges() const
{ {
if (!pePtr_) if (!pePtr_)
{ {
//// Invert edges //calcEdges(true);
//pePtr_ = new labelListList(nPoints()); calcEdges(false);
//invertManyToMany(nPoints(), edges(), *pePtr_);
calcEdges(true);
} }
return *pePtr_; return *pePtr_;
@ -491,12 +490,53 @@ const labelListList& primitiveMesh::faceEdges() const
{ {
if (!fePtr_) if (!fePtr_)
{ {
calcEdges(true); if (debug)
{
Pout<< "primitiveMesh::faceEdges() : "
<< "calculating faceEdges" << endl;
}
//calcEdges(true);
const faceList& fcs = faces();
const labelListList& pe = pointEdges();
const edgeList& es = edges();
fePtr_ = new labelListList(fcs.size());
labelListList& faceEdges = *fePtr_;
forAll(fcs, faceI)
{
const face& f = fcs[faceI];
labelList& fEdges = faceEdges[faceI];
fEdges.setSize(f.size());
forAll(f, fp)
{
label pointI = f[fp];
label nextPointI = f[f.fcIndex(fp)];
// Find edge between pointI, nextPontI
const labelList& pEdges = pe[pointI];
forAll(pEdges, i)
{
label edgeI = pEdges[i];
if (es[edgeI].otherVertex(pointI) == nextPointI)
{
fEdges[fp] = edgeI;
break;
}
}
}
}
} }
return *fePtr_; return *fePtr_;
} }
void primitiveMesh::clearOutEdges() void primitiveMesh::clearOutEdges()
{ {
deleteDemandDrivenData(edgesPtr_); deleteDemandDrivenData(edgesPtr_);

View File

@ -41,8 +41,7 @@ extern "C"
# include "parmetis.h" # include "parmetis.h"
} }
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
@ -57,6 +56,8 @@ namespace Foam
} }
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
//- Does prevention of 0 cell domains and calls parmetis. //- Does prevention of 0 cell domains and calls parmetis.
Foam::label Foam::parMetisDecomp::decompose Foam::label Foam::parMetisDecomp::decompose
( (
@ -76,6 +77,16 @@ Foam::label Foam::parMetisDecomp::decompose
// Number of dimensions // Number of dimensions
int nDims = 3; int nDims = 3;
if (cellCentres.size() != xadj.size()-1)
{
FatalErrorIn("parMetisDecomp::decompose(..)")
<< "cellCentres:" << cellCentres.size()
<< " xadj:" << xadj.size()
<< abort(FatalError);
}
// Get number of cells on all processors // Get number of cells on all processors
List<int> nLocalCells(Pstream::nProcs()); List<int> nLocalCells(Pstream::nProcs());
nLocalCells[Pstream::myProcNo()] = xadj.size()-1; nLocalCells[Pstream::myProcNo()] = xadj.size()-1;
@ -106,12 +117,12 @@ Foam::label Foam::parMetisDecomp::decompose
// Make sure every domain has at least one cell // Make sure every domain has at least one cell
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// (Metis falls over with zero sized domains) // (Metis falls over with zero sized domains)
// Trickle cells from processors that have them down to those that // Trickle cells from processors that have them up to those that
// don't. // don't.
// Number of cells to send down (is same as number of cells next processor // Number of cells to send to the next processor
// has to receive) // (is same as number of cells next processor has to receive)
List<int> nSendCells(Pstream::nProcs(), 0); List<int> nSendCells(Pstream::nProcs(), 0);
for (label procI = nLocalCells.size()-1; procI >=1; procI--) for (label procI = nLocalCells.size()-1; procI >=1; procI--)
@ -135,6 +146,15 @@ Foam::label Foam::parMetisDecomp::decompose
Field<int> prevCellWeights(fromPrevProc); Field<int> prevCellWeights(fromPrevProc);
Field<int> prevFaceWeights(fromPrevProc); Field<int> prevFaceWeights(fromPrevProc);
if (prevXadj.size() != nSendCells[Pstream::myProcNo()-1])
{
FatalErrorIn("parMetisDecomp::decompose(..)")
<< "Expected from processor " << Pstream::myProcNo()-1
<< " connectivity for " << nSendCells[Pstream::myProcNo()-1]
<< " nCells but only received " << prevXadj.size()
<< abort(FatalError);
}
// Insert adjncy // Insert adjncy
prepend(prevAdjncy, adjncy); prepend(prevAdjncy, adjncy);
// Adapt offsets and prepend xadj // Adapt offsets and prepend xadj
@ -222,6 +242,14 @@ Foam::label Foam::parMetisDecomp::decompose
} }
if (nLocalCells[Pstream::myProcNo()] != (xadj.size()-1))
{
FatalErrorIn("parMetisDecomp::decompose(..)")
<< "Have connectivity for " << xadj.size()-1
<< " cells but nLocalCells:" << nLocalCells[Pstream::myProcNo()]
<< abort(FatalError);
}
// Weight info // Weight info
int wgtFlag = 0; int wgtFlag = 0;
int* vwgtPtr = NULL; int* vwgtPtr = NULL;
@ -292,6 +320,15 @@ Foam::label Foam::parMetisDecomp::decompose
List<int> nextFinalDecomp(fromNextProc); List<int> nextFinalDecomp(fromNextProc);
if (nextFinalDecomp.size() != nSendCells[Pstream::myProcNo()])
{
FatalErrorIn("parMetisDecomp::decompose(..)")
<< "Expected from processor " << Pstream::myProcNo()+1
<< " decomposition for " << nSendCells[Pstream::myProcNo()]
<< " nCells but only received " << nextFinalDecomp.size()
<< abort(FatalError);
}
append(nextFinalDecomp, finalDecomp); append(nextFinalDecomp, finalDecomp);
} }

View File

@ -24,7 +24,6 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "SortableList.H"
#include "dynamicRefineFvMesh.H" #include "dynamicRefineFvMesh.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
#include "volFields.H" #include "volFields.H"
@ -32,7 +31,6 @@ License
#include "surfaceFields.H" #include "surfaceFields.H"
#include "fvCFD.H" #include "fvCFD.H"
#include "syncTools.H" #include "syncTools.H"
#include "ListListOps.H"
#include "pointFields.H" #include "pointFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -399,7 +399,7 @@ bool Foam::octreeDataFaceList::overlaps
const treeBoundBox& sampleBb const treeBoundBox& sampleBb
) const ) const
{ {
return sampleBb.intersects(allBb_[index]); return sampleBb.overlaps(allBb_[index]);
} }

View File

@ -32,7 +32,6 @@ License
#include "octreeDataFace.H" #include "octreeDataFace.H"
#include "octree.H" #include "octree.H"
#include "OFstream.H" #include "OFstream.H"
#include "SortableList.H"
#include "IndirectList.H" #include "IndirectList.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

View File

@ -29,6 +29,8 @@ License
#include "ListListOps.H" #include "ListListOps.H"
#include "meshSearch.H" #include "meshSearch.H"
#include "mapDistribute.H" #include "mapDistribute.H"
#include "meshTools.H"
#include "OFstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -47,16 +49,18 @@ void Foam::directMappedPolyPatch::collectSamples
( (
pointField& samples, pointField& samples,
labelList& patchFaceProcs, labelList& patchFaceProcs,
labelList& patchFaces labelList& patchFaces,
pointField& patchFc
) const ) const
{ {
const vectorField::subField fc = this->faceCentres();
// Collect all sample points and the faces they come from. // Collect all sample points and the faces they come from.
List<pointField> globalFc(Pstream::nProcs());
List<pointField> globalSamples(Pstream::nProcs()); List<pointField> globalSamples(Pstream::nProcs());
labelListList globalFaces(Pstream::nProcs()); labelListList globalFaces(Pstream::nProcs());
globalSamples[Pstream::myProcNo()] = fc+offset_; globalFc[Pstream::myProcNo()] = this->faceCentres();
globalSamples[Pstream::myProcNo()] = globalFc[Pstream::myProcNo()]+offset_;
globalFaces[Pstream::myProcNo()] = identity(size()); globalFaces[Pstream::myProcNo()] = identity(size());
// Distribute to all processors // Distribute to all processors
@ -64,6 +68,8 @@ void Foam::directMappedPolyPatch::collectSamples
Pstream::scatterList(globalSamples); Pstream::scatterList(globalSamples);
Pstream::gatherList(globalFaces); Pstream::gatherList(globalFaces);
Pstream::scatterList(globalFaces); Pstream::scatterList(globalFaces);
Pstream::gatherList(globalFc);
Pstream::scatterList(globalFc);
// Rework into straight list // Rework into straight list
samples = ListListOps::combine<pointField> samples = ListListOps::combine<pointField>
@ -76,6 +82,11 @@ void Foam::directMappedPolyPatch::collectSamples
globalFaces, globalFaces,
accessOp<labelList>() accessOp<labelList>()
); );
patchFc = ListListOps::combine<pointField>
(
globalFc,
accessOp<pointField>()
);
patchFaceProcs.setSize(patchFaces.size()); patchFaceProcs.setSize(patchFaces.size());
labelList nPerProc labelList nPerProc
@ -103,11 +114,14 @@ void Foam::directMappedPolyPatch::findSamples
( (
const pointField& samples, const pointField& samples,
labelList& sampleCellProcs, labelList& sampleCellProcs,
labelList& sampleCells labelList& sampleCells,
pointField& sampleCc
) const ) const
{ {
sampleCellProcs.setSize(samples.size()); sampleCellProcs.setSize(samples.size());
sampleCells.setSize(samples.size()); sampleCells.setSize(samples.size());
sampleCc.setSize(samples.size());
sampleCc = point(-GREAT, -GREAT, -GREAT);
{ {
// Octree based search engine // Octree based search engine
@ -124,6 +138,8 @@ void Foam::directMappedPolyPatch::findSamples
else else
{ {
sampleCellProcs[sampleI] = Pstream::myProcNo(); sampleCellProcs[sampleI] = Pstream::myProcNo();
sampleCc[sampleI] =
boundaryMesh().mesh().cellCentres()[sampleCells[sampleI]];
} }
} }
} }
@ -136,6 +152,9 @@ void Foam::directMappedPolyPatch::findSamples
Pstream::listCombineGather(sampleCellProcs, maxEqOp<label>()); Pstream::listCombineGather(sampleCellProcs, maxEqOp<label>());
Pstream::listCombineScatter(sampleCellProcs); Pstream::listCombineScatter(sampleCellProcs);
Pstream::listCombineGather(sampleCc, maxEqOp<point>());
Pstream::listCombineScatter(sampleCc);
if (debug) if (debug)
{ {
Info<< "directMappedPolyPatch::findSamples : " << endl; Info<< "directMappedPolyPatch::findSamples : " << endl;
@ -143,7 +162,8 @@ void Foam::directMappedPolyPatch::findSamples
{ {
Info<< " " << sampleI << " coord:" << samples[sampleI] Info<< " " << sampleI << " coord:" << samples[sampleI]
<< " found on processor:" << sampleCellProcs[sampleI] << " found on processor:" << sampleCellProcs[sampleI]
<< " in cell:" << sampleCells[sampleI] << endl; << " in cell:" << sampleCells[sampleI]
<< " with cc:" << sampleCc[sampleI] << endl;
} }
} }
@ -213,12 +233,14 @@ void Foam::directMappedPolyPatch::calcMapping() const
pointField samples; pointField samples;
labelList patchFaceProcs; labelList patchFaceProcs;
labelList patchFaces; labelList patchFaces;
collectSamples(samples, patchFaceProcs, patchFaces); pointField patchFc;
collectSamples(samples, patchFaceProcs, patchFaces, patchFc);
// Find processor and cell samples are in // Find processor and cell samples are in
labelList sampleCellProcs; labelList sampleCellProcs;
labelList sampleCells; labelList sampleCells;
findSamples(samples, sampleCellProcs, sampleCells); pointField sampleCc;
findSamples(samples, sampleCellProcs, sampleCells, sampleCc);
// Now we have all the data we need: // Now we have all the data we need:
@ -227,6 +249,60 @@ void Foam::directMappedPolyPatch::calcMapping() const
// - cell sample is in (so source when mapping) // - cell sample is in (so source when mapping)
// sampleCells, sampleCellProcs. // sampleCells, sampleCellProcs.
if (debug && Pstream::master())
{
OFstream str
(
boundaryMesh().mesh().time().path()
/ name()
+ "_directMapped.obj"
);
Pout<< "Dumping mapping as lines from patch faceCentres to"
<< " sampled cellCentres to file " << str.name() << endl;
label vertI = 0;
forAll(patchFc, i)
{
meshTools::writeOBJ(str, patchFc[i]);
vertI++;
meshTools::writeOBJ(str, sampleCc[i]);
vertI++;
str << "l " << vertI-1 << ' ' << vertI << nl;
}
}
// Check that actual offset vector (sampleCc - patchFc) is more or less
// constant.
if (Pstream::master())
{
const scalarField magOffset(mag(sampleCc - patchFc));
const scalar avgOffset(average(magOffset));
forAll(magOffset, sampleI)
{
if (mag(magOffset[sampleI]-avgOffset) > 0.001*avgOffset)
{
WarningIn("directMappedPolyPatch::calcMapping() const")
<< "The actual cell centres picked up using offset "
<< offset_ << " are not" << endl
<< " on a single plane."
<< " This might give numerical problems." << endl
<< " At patchface " << patchFc[sampleI]
<< " the sampled cell " << sampleCc[sampleI] << endl
<< " is not on a plane " << avgOffset
<< " offset from the patch." << endl
<< " You might want to shift your plane offset."
<< " Set the debug flag to get a dump of sampled cells."
<< endl;
break;
}
}
}
// Determine schedule. // Determine schedule.
mapDistribute distMap(sampleCellProcs, patchFaceProcs); mapDistribute distMap(sampleCellProcs, patchFaceProcs);

View File

@ -82,7 +82,8 @@ class directMappedPolyPatch
( (
pointField&, pointField&,
labelList& patchFaceProcs, labelList& patchFaceProcs,
labelList& patchFaces labelList& patchFaces,
pointField& patchFc
) const; ) const;
//- Find cells containing samples //- Find cells containing samples
@ -90,7 +91,8 @@ class directMappedPolyPatch
( (
const pointField&, const pointField&,
labelList& sampleCellProcs, labelList& sampleCellProcs,
labelList& sampleCells labelList& sampleCells,
pointField& sampleCc
) const; ) const;
//- Calculate matching //- Calculate matching

View File

@ -40,7 +40,7 @@ namespace Foam
// Does bb intersect a sphere around sample? Or is any corner point of bb // Does bb intersect a sphere around sample? Or is any corner point of bb
// closer than nearestDistSqr to sample. // closer than nearestDistSqr to sample.
template <class Type> template <class Type>
bool indexedOctree<Type>::intersects bool indexedOctree<Type>::overlaps
( (
const point& p0, const point& p0,
const point& p1, const point& p1,
@ -84,7 +84,7 @@ bool indexedOctree<Type>::intersects
// Does bb intersect a sphere around sample? Or is any corner point of bb // Does bb intersect a sphere around sample? Or is any corner point of bb
// closer than nearestDistSqr to sample. // closer than nearestDistSqr to sample.
template <class Type> template <class Type>
bool indexedOctree<Type>::intersects bool indexedOctree<Type>::overlaps
( (
const treeBoundBox& parentBb, const treeBoundBox& parentBb,
const direction octant, const direction octant,
@ -94,7 +94,7 @@ bool indexedOctree<Type>::intersects
{ {
//- Speeded up version of //- Speeded up version of
// treeBoundBox subBb(parentBb.subBbox(mid, octant)) // treeBoundBox subBb(parentBb.subBbox(mid, octant))
// intersects // overlaps
// ( // (
// subBb.min(), // subBb.min(),
// subBb.max(), // subBb.max(),
@ -136,7 +136,7 @@ bool indexedOctree<Type>::intersects
const point mid(0.5*(min+max)); const point mid(0.5*(min+max));
return intersects(mid, other, nearestDistSqr, sample); return overlaps(mid, other, nearestDistSqr, sample);
} }
@ -567,7 +567,7 @@ void indexedOctree<Type>::findNearest
const treeBoundBox& subBb = nodes_[subNodeI].bb_; const treeBoundBox& subBb = nodes_[subNodeI].bb_;
if (intersects(subBb.min(), subBb.max(), nearestDistSqr, sample)) if (overlaps(subBb.min(), subBb.max(), nearestDistSqr, sample))
{ {
findNearest findNearest
( (
@ -584,7 +584,7 @@ void indexedOctree<Type>::findNearest
{ {
if if
( (
intersects overlaps
( (
nod.bb_, nod.bb_,
octant, octant,
@ -639,7 +639,7 @@ void indexedOctree<Type>::findNearest
{ {
const treeBoundBox& subBb = nodes_[getNode(index)].bb_; const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
if (subBb.intersects(tightest)) if (subBb.overlaps(tightest))
{ {
findNearest findNearest
( (
@ -657,7 +657,7 @@ void indexedOctree<Type>::findNearest
{ {
const treeBoundBox subBb(nodeBb.subBbox(octant)); const treeBoundBox subBb(nodeBb.subBbox(octant));
if (subBb.intersects(tightest)) if (subBb.overlaps(tightest))
{ {
shapes_.findNearest shapes_.findNearest
( (
@ -1121,7 +1121,7 @@ void indexedOctree<Type>::findBox
{ {
const treeBoundBox& subBb = nodes_[getNode(index)].bb_; const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
if (subBb.intersects(searchBox)) if (subBb.overlaps(searchBox))
{ {
findBox(getNode(index), searchBox, elements); findBox(getNode(index), searchBox, elements);
} }
@ -1130,7 +1130,7 @@ void indexedOctree<Type>::findBox
{ {
const treeBoundBox subBb(nodeBb.subBbox(octant)); const treeBoundBox subBb(nodeBb.subBbox(octant));
if (subBb.intersects(searchBox)) if (subBb.overlaps(searchBox))
{ {
const labelList& indices = contents_[getContent(index)]; const labelList& indices = contents_[getContent(index)];

View File

@ -36,9 +36,9 @@ SourceFiles
#ifndef indexedOctree_H #ifndef indexedOctree_H
#define indexedOctree_H #define indexedOctree_H
#include "treeBoundBox.H"
#include "pointIndexHit.H" #include "pointIndexHit.H"
#include "FixedList.H" #include "FixedList.H"
#include "treeBoundBox.H"
#include "Ostream.H" #include "Ostream.H"
#include "labelHashSet.H" #include "labelHashSet.H"
#include "labelBits.H" #include "labelBits.H"
@ -146,7 +146,7 @@ private:
//- Like above but now bb is implicitly provided as parent bb + mid //- Like above but now bb is implicitly provided as parent bb + mid
// + octant // + octant
static bool intersects static bool overlaps
( (
const treeBoundBox& parentBb, const treeBoundBox& parentBb,
const direction octant, const direction octant,
@ -497,7 +497,7 @@ public:
//- Helper: does bb intersect a sphere around sample? Or is any //- Helper: does bb intersect a sphere around sample? Or is any
// corner point of bb closer than nearestDistSqr to sample. // corner point of bb closer than nearestDistSqr to sample.
static bool intersects static bool overlaps
( (
const point& bbMin, const point& bbMin,
const point& bbMax, const point& bbMax,

View File

@ -137,11 +137,11 @@ bool Foam::treeDataCell::overlaps
{ {
if (cacheBb_) if (cacheBb_)
{ {
return cubeBb.intersects(bbs_[index]); return cubeBb.overlaps(bbs_[index]);
} }
else else
{ {
return cubeBb.intersects(calcCellBb(cellLabels_[index])); return cubeBb.overlaps(calcCellBb(cellLabels_[index]));
} }
} }

View File

@ -110,11 +110,11 @@ bool Foam::treeDataEdge::overlaps
{ {
if (cacheBb_) if (cacheBb_)
{ {
return cubeBb.intersects(bbs_[index]); return cubeBb.overlaps(bbs_[index]);
} }
else else
{ {
return cubeBb.intersects(calcBb(edgeLabels_[index])); return cubeBb.overlaps(calcBb(edgeLabels_[index]));
} }
} }

View File

@ -412,14 +412,14 @@ bool Foam::treeDataFace::overlaps
// 1. Quick rejection: bb does not intersect face bb at all // 1. Quick rejection: bb does not intersect face bb at all
if (cacheBb_) if (cacheBb_)
{ {
if (!cubeBb.intersects(bbs_[index])) if (!cubeBb.overlaps(bbs_[index]))
{ {
return false; return false;
} }
} }
else else
{ {
if (!cubeBb.intersects(calcBb(faceLabels_[index]))) if (!cubeBb.overlaps(calcBb(faceLabels_[index])))
{ {
return false; return false;
} }

View File

@ -284,13 +284,13 @@ bool Foam::treeDataTriSurface::overlaps
triBb.max() = max(triBb.max(), p2); triBb.max() = max(triBb.max(), p2);
//- For testing: robust one //- For testing: robust one
//return cubeBb.intersects(triBb); //return cubeBb.overlaps(triBb);
//- Exact test of triangle intersecting bb //- Exact test of triangle intersecting bb
// Quick rejection. If whole bounding box of tri is outside cubeBb then // Quick rejection. If whole bounding box of tri is outside cubeBb then
// there will be no intersection. // there will be no intersection.
if (!cubeBb.intersects(triBb)) if (!cubeBb.overlaps(triBb))
{ {
return false; return false;
} }

View File

@ -94,6 +94,12 @@ public:
index_(-1) index_(-1)
{} {}
//- Construct from Istream
PointIndexHit(Istream& is)
{
is >> *this;
}
// Member Functions // Member Functions
@ -193,13 +199,45 @@ public:
friend Ostream& operator<< (Ostream& os, const PointIndexHit& pHit) friend Ostream& operator<< (Ostream& os, const PointIndexHit& pHit)
{ {
return os << pHit.hit_ << token::SPACE << pHit.hitPoint_ if (os.format() == IOstream::ASCII)
<< token::SPACE << pHit.index_; {
os << pHit.hit_ << token::SPACE << pHit.hitPoint_
<< token::SPACE << pHit.index_;
}
else
{
os.write
(
reinterpret_cast<const char*>(&pHit),
sizeof(PointIndexHit)
);
}
// Check state of Ostream
os.check("Ostream& operator<<(Ostream&, const PointIndexHit&)");
return os;
} }
friend Istream& operator>>(Istream& is, PointIndexHit& pHit) friend Istream& operator>>(Istream& is, PointIndexHit& pHit)
{ {
return is >> pHit.hit_ >> pHit.hitPoint_ >> pHit.index_; if (is.format() == IOstream::ASCII)
{
return is >> pHit.hit_ >> pHit.hitPoint_ >> pHit.index_;
}
else
{
is.read
(
reinterpret_cast<char*>(&pHit),
sizeof(PointIndexHit)
);
}
// Check state of Istream
is.check("Istream& operator>>(Istream&, PointIndexHit&)");
return is;
} }
}; };

View File

@ -113,7 +113,7 @@ bool Foam::octreeDataCell::overlaps
const treeBoundBox& cubeBb const treeBoundBox& cubeBb
) const ) const
{ {
return cubeBb.intersects(bbs_[index]); return cubeBb.overlaps(bbs_[index]);
} }

View File

@ -107,7 +107,7 @@ bool Foam::octreeDataEdges::overlaps
const treeBoundBox& sampleBb const treeBoundBox& sampleBb
) const ) const
{ {
return sampleBb.intersects(allBb_[index]); return sampleBb.overlaps(allBb_[index]);
} }

View File

@ -507,12 +507,12 @@ bool Foam::octreeDataFace::overlaps
const treeBoundBox& sampleBb const treeBoundBox& sampleBb
) const ) const
{ {
//return sampleBb.intersects(allBb_[index]); //return sampleBb.overlaps(allBb_[index]);
//- Exact test of face intersecting bb //- Exact test of face intersecting bb
// 1. Quick rejection: bb does not intersect face bb at all // 1. Quick rejection: bb does not intersect face bb at all
if (!sampleBb.intersects(allBb_[index])) if (!sampleBb.overlaps(allBb_[index]))
{ {
return false; return false;
} }

View File

@ -39,7 +39,14 @@ Description
namespace Foam namespace Foam
{ {
typedef PointIndexHit<point> pointIndexHit;
typedef PointIndexHit<point> pointIndexHit;
//- Specify data associated with pointIndexHit type is contiguous
template<>
inline bool contiguous<pointIndexHit>() {return true;}
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -297,6 +297,45 @@ Foam::treeBoundBox Foam::treeBoundBox::subBbox
} }
bool Foam::treeBoundBox::overlaps
(
const point& centre,
const scalar radiusSqr
) const
{
// Find out where centre is in relation to bb.
// Find nearest point on bb.
scalar distSqr = 0;
for (direction dir = 0; dir < vector::nComponents; dir++)
{
scalar d0 = min()[dir] - centre[dir];
scalar d1 = max()[dir] - centre[dir];
if ((d0 > 0) != (d1 > 0))
{
// centre inside both extrema. This component does not add any
// distance.
}
else if (Foam::mag(d0) < Foam::mag(d1))
{
distSqr += d0*d0;
}
else
{
distSqr += d1*d1;
}
if (distSqr > radiusSqr)
{
return false;
}
}
return true;
}
// line intersection. Returns true if line (start to end) inside // line intersection. Returns true if line (start to end) inside
// bb or intersects bb. Sets pt to intersection. // bb or intersects bb. Sets pt to intersection.
// //

View File

@ -263,8 +263,11 @@ public:
FixedList<direction, 8>& octantOrder FixedList<direction, 8>& octantOrder
) const; ) const;
//- Intersects other boundingbox? //- Overlaps other boundingbox?
inline bool intersects(const treeBoundBox&) const; inline bool overlaps(const treeBoundBox&) const;
//- Overlaps boundingSphere (centre + sqr(radius))?
bool overlaps(const point&, const scalar radiusSqr) const;
//- Intersects segment; set point to intersection position, //- Intersects segment; set point to intersection position,
// return true if intersection found. // return true if intersection found.

View File

@ -24,9 +24,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "error.H"
#include "treeBoundBox.H" #include "treeBoundBox.H"
#include "point.H"
#include "Random.H" #include "Random.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -414,9 +412,9 @@ inline void treeBoundBox::searchOrder
// true if bb's intersect or overlap. // true if bb's intersect or overlap.
// Note: <= to make sure we catch all. // Note: <= to make sure we catch all.
inline bool treeBoundBox::intersects(const treeBoundBox& bb) const inline bool treeBoundBox::overlaps(const treeBoundBox& bb) const
{ {
return boundBox::intersects(bb); return boundBox::overlaps(bb);
} }

View File

@ -798,7 +798,7 @@ bool treeNode<Type>::findTightest
// Node: recurse into subnodes // Node: recurse into subnodes
const treeNode<Type>* subNodePtr = getNodePtr(octant); const treeNode<Type>* subNodePtr = getNodePtr(octant);
if (subNodePtr->bb().intersects(tightest)) if (subNodePtr->bb().overlaps(tightest))
{ {
// there might be a better fit inside this subNode // there might be a better fit inside this subNode
changed |= changed |=
@ -815,7 +815,7 @@ bool treeNode<Type>::findTightest
// Leaf: let leaf::find handle this // Leaf: let leaf::find handle this
const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant); const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant);
if (subLeafPtr->bb().intersects(tightest)) if (subLeafPtr->bb().overlaps(tightest))
{ {
// there might be a better fit inside this subLeaf // there might be a better fit inside this subLeaf
changed |= changed |=
@ -884,7 +884,7 @@ bool treeNode<Type>::findNearest
// Node // Node
const treeNode<Type>* subNodePtr = getNodePtr(octant); const treeNode<Type>* subNodePtr = getNodePtr(octant);
if (subNodePtr->bb().intersects(tightest)) if (subNodePtr->bb().overlaps(tightest))
{ {
// there might be a better fit inside this subNode // there might be a better fit inside this subNode
changed |= changed |=
@ -903,7 +903,7 @@ bool treeNode<Type>::findNearest
// Leaf: let leaf::find handle this // Leaf: let leaf::find handle this
const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant); const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant);
if (subLeafPtr->bb().intersects(tightest)) if (subLeafPtr->bb().overlaps(tightest))
{ {
// there might be a better fit inside this subNode // there might be a better fit inside this subNode
changed |= changed |=
@ -975,7 +975,7 @@ bool treeNode<Type>::findNearest
// Node // Node
const treeNode<Type>* subNodePtr = getNodePtr(octant); const treeNode<Type>* subNodePtr = getNodePtr(octant);
if (subNodePtr->bb().intersects(tightest)) if (subNodePtr->bb().overlaps(tightest))
{ {
// there might be a better fit inside this subNode // there might be a better fit inside this subNode
changed |= changed |=
@ -995,7 +995,7 @@ bool treeNode<Type>::findNearest
// Leaf: let leaf::find handle this // Leaf: let leaf::find handle this
const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant); const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant);
if (subLeafPtr->bb().intersects(tightest)) if (subLeafPtr->bb().overlaps(tightest))
{ {
// there might be a better fit inside this subNode // there might be a better fit inside this subNode
changed |= changed |=
@ -1060,7 +1060,7 @@ bool treeNode<Type>::findBox
// Node // Node
const treeNode<Type>* subNodePtr = getNodePtr(octant); const treeNode<Type>* subNodePtr = getNodePtr(octant);
if (subNodePtr->bb().intersects(box)) if (subNodePtr->bb().overlaps(box))
{ {
// Visit sub node. // Visit sub node.
changed |= subNodePtr->findBox(shapes, box, elements); changed |= subNodePtr->findBox(shapes, box, elements);
@ -1071,7 +1071,7 @@ bool treeNode<Type>::findBox
// Leaf: let leaf::find handle this // Leaf: let leaf::find handle this
const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant); const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant);
if (subLeafPtr->bb().intersects(box)) if (subLeafPtr->bb().overlaps(box))
{ {
// Visit sub leaf. // Visit sub leaf.
changed |= subLeafPtr->findBox(shapes, box, elements); changed |= subLeafPtr->findBox(shapes, box, elements);

View File

@ -26,7 +26,6 @@ License
#include "searchableSphere.H" #include "searchableSphere.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
#include "SortableList.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

View File

@ -27,8 +27,6 @@ License
#include "intersectedSurface.H" #include "intersectedSurface.H"
#include "surfaceIntersection.H" #include "surfaceIntersection.H"
#include "faceList.H" #include "faceList.H"
#include "SortableList.H"
#include "triSurfaceTools.H"
#include "faceTriangulation.H" #include "faceTriangulation.H"
#include "treeBoundBox.H" #include "treeBoundBox.H"
#include "OFstream.H" #include "OFstream.H"

View File

@ -385,12 +385,12 @@ bool Foam::octreeDataTriSurface::overlaps
const treeBoundBox& cubeBb const treeBoundBox& cubeBb
) const ) const
{ {
//return cubeBb.intersects(allBb_[index]); //return cubeBb.overlaps(allBb_[index]);
//- Exact test of triangle intersecting bb //- Exact test of triangle intersecting bb
// Quick rejection. // Quick rejection.
if (!cubeBb.intersects(allBb_[index])) if (!cubeBb.overlaps(allBb_[index]))
{ {
return false; return false;
} }

View File

@ -54,7 +54,7 @@ bool Foam::treeLeaf<Foam::octreeDataTriSurface>::findNearest
label faceI = indices_[i]; label faceI = indices_[i];
// Quick rejection test. // Quick rejection test.
if (tightest.intersects(allBb[faceI])) if (tightest.overlaps(allBb[faceI]))
{ {
// Full calculation // Full calculation
scalar dist = shapes.calcNearest(faceI, sample, nearest); scalar dist = shapes.calcNearest(faceI, sample, nearest);

View File

@ -101,6 +101,7 @@ bool Foam::triangleFuncs::intersectAxesBundle
// Since direction is coordinate axis there is no need to do projection, // Since direction is coordinate axis there is no need to do projection,
// we can directly check u,v components for inclusion in triangle. // we can directly check u,v components for inclusion in triangle.
scalar localScale = max(max(magSqr(V10), magSqr(V20)), 1.0);
// Get other components // Get other components
label i1 = (i0 + 1) % 3; label i1 = (i0 + 1) % 3;
@ -114,8 +115,11 @@ bool Foam::triangleFuncs::intersectAxesBundle
scalar det = v2*u1 - u2*v1; scalar det = v2*u1 - u2*v1;
// Fix for V0:(-31.71428 0 -15.10714) V10:(-1.285715 8.99165e-16 -1.142858) V20:(0 0 -1.678573) i0:0 // Fix for V0:(-31.71428 0 -15.10714)
if (Foam::mag(det)/max(max(mag(V10),mag(V20)),1) < SMALL) // V10:(-1.285715 8.99165e-16 -1.142858)
// V20:(0 0 -1.678573)
// i0:0
if (Foam::mag(det)/localScale < SMALL)
{ {
// Triangle parallel to dir // Triangle parallel to dir
return false; return false;
@ -132,7 +136,7 @@ bool Foam::triangleFuncs::intersectAxesBundle
scalar beta = 0; scalar beta = 0;
bool inter = false; bool inter = false;
if (Foam::mag(u1) < SMALL) if (Foam::mag(u1)/localScale < SMALL)
{ {
beta = u0/u2; beta = u0/u2;
if ((beta >= 0) && (beta <= 1)) if ((beta >= 0) && (beta <= 1))

View File

@ -31,6 +31,7 @@ License
#include "Time.H" #include "Time.H"
#include "boundBox.H" #include "boundBox.H"
#include "SortableList.H" #include "SortableList.H"
#include "PackedList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -626,7 +627,7 @@ surfacePatchList triSurface::calcPatches(labelList& faceMap) const
{ {
sortedRegion[faceI] = operator[](faceI).region(); sortedRegion[faceI] = operator[](faceI).region();
} }
sortedRegion.stableSort(); sortedRegion.sort();
faceMap = sortedRegion.indices(); faceMap = sortedRegion.indices();
@ -743,6 +744,26 @@ triSurface::triSurface
{} {}
triSurface::triSurface
(
List<labelledTri>& triangles,
const geometricSurfacePatchList& patches,
pointField& points,
const bool reUse
)
:
PrimitivePatch<labelledTri, ::Foam::List, pointField>
(
triangles,
points,
reUse
),
patches_(patches),
sortedEdgeFacesPtr_(NULL),
edgeOwnerPtr_(NULL)
{}
triSurface::triSurface triSurface::triSurface
( (
const List<labelledTri>& triangles, const List<labelledTri>& triangles,
@ -1148,9 +1169,7 @@ triSurface triSurface::subsetMesh
} }
// Construct subsurface // Construct subsurface
triSurface subSurface(newTriangles, patches(), newPoints); return triSurface(newTriangles, patches(), newPoints, true);
return subSurface;
} }
@ -1187,30 +1206,36 @@ void triSurface::write(const Time& d) const
void triSurface::writeStats(Ostream& os) const void triSurface::writeStats(Ostream& os) const
{ {
// Calculate bounding box without any additional addressing // Unfortunately nPoints constructs meshPoints() so do compact version
// Copy of treeBoundBox code. Cannot use meshTools from triSurface... // ourselves.
PackedList<1> pointIsUsed(points().size());
pointIsUsed = 0U;
label nPoints = 0;
boundBox bb boundBox bb
( (
point(VGREAT, VGREAT, VGREAT), point(VGREAT, VGREAT, VGREAT),
point(-VGREAT, -VGREAT, -VGREAT) point(-VGREAT, -VGREAT, -VGREAT)
); );
forAll(*this, triI) forAll(*this, triI)
{ {
const labelledTri& f = operator[](triI); const labelledTri& f = operator[](triI);
forAll(f, fp) forAll(f, fp)
{ {
const point& pt = points()[f[fp]]; label pointI = f[fp];
bb.min() = ::Foam::min(bb.min(), pt); if (pointIsUsed.set(pointI, 1))
bb.max() = ::Foam::max(bb.max(), pt); {
bb.min() = ::Foam::min(bb.min(), points()[pointI]);
bb.max() = ::Foam::max(bb.max(), points()[pointI]);
nPoints++;
}
} }
} }
// Unfortunately nPoints constructs meshPoints() ...
os << "Triangles : " << size() << endl os << "Triangles : " << size() << endl
//<< "Edges : " << nEdges() << endl << "Vertices : " << nPoints << endl
<< "Vertices : " << nPoints() << endl
<< "Bounding Box : " << bb << endl; << "Bounding Box : " << bb << endl;
} }

View File

@ -36,9 +36,9 @@ SourceFiles
#ifndef triSurface_H #ifndef triSurface_H
#define triSurface_H #define triSurface_H
#include "PrimitivePatch.H"
#include "pointField.H" #include "pointField.H"
#include "labelledTri.H" #include "labelledTri.H"
#include "PrimitivePatch.H"
#include "boolList.H" #include "boolList.H"
#include "geometricSurfacePatchList.H" #include "geometricSurfacePatchList.H"
#include "surfacePatchList.H" #include "surfacePatchList.H"
@ -215,6 +215,15 @@ public:
const pointField& const pointField&
); );
//- Construct from triangles, patches, points. Reuse storage.
triSurface
(
List<labelledTri>&,
const geometricSurfacePatchList&,
pointField&,
const bool reUse
);
//- Construct from triangles, points. Set patchnames to default. //- Construct from triangles, points. Set patchnames to default.
triSurface(const List<labelledTri>&, const pointField&); triSurface(const List<labelledTri>&, const pointField&);

View File

@ -22,7 +22,7 @@ dictionaryReplacement
inlet inlet
{ {
type directMappedPatch; type directMappedPatch;
offset (0.05 0 0); offset (0.0495 0 0);
} }
} }
} }