Commit fe58db2e authored by henry's avatar henry
Browse files
parents 485a2549 accc0399
......@@ -504,7 +504,7 @@ int main(int argc, char *argv[])
!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();
bbsTargetSet[procITarget] = true;
if (bbsTarget[procITarget].intersects(bbSource))
if (bbsTarget[procITarget].overlaps(bbSource))
{
if (consistent)
{
......
......@@ -86,28 +86,7 @@ void Foam::SortableList<Type>::sort()
indices_[i] = i;
}
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::sort(indices_, less(*this));
Foam::stableSort(indices_, less(*this));
List<Type> tmpValues(this->size());
......
......@@ -109,12 +109,9 @@ public:
//- Size the list. If grow can cause undefined indices (until next sort)
void setSize(const label);
//- Sort the list (if changed after construction time)
//- (stable) sort the list (if changed after construction time)
void sort();
//- Sort the list (if changed after construction time)
void stableSort();
// Member Operators
......
......@@ -118,7 +118,7 @@ public:
// Query
//- Intersects other boundingbox?
bool intersects(const boundBox& bb) const
bool overlaps(const boundBox& bb) const
{
if
(
......
......@@ -31,7 +31,11 @@ License
// * * * * * * * * * * * * * 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
List<labelPair> allComms;
......@@ -40,16 +44,16 @@ void Foam::mapDistribute::calcSchedule() const
HashSet<labelPair, labelPair::Hash<> > commsSet(Pstream::nProcs());
// Find what communication is required
forAll(subMap_, procI)
forAll(subMap, procI)
{
if (procI != Pstream::myProcNo())
{
if (subMap_[procI].size() > 0)
if (subMap[procI].size() > 0)
{
// I need to send to procI
commsSet.insert(labelPair(Pstream::myProcNo(), procI));
}
if (constructMap_[procI].size() > 0)
if (constructMap[procI].size() > 0)
{
// I need to receive from procI
commsSet.insert(labelPair(procI, Pstream::myProcNo()));
......@@ -120,13 +124,7 @@ void Foam::mapDistribute::calcSchedule() const
);
// Processors involved in my schedule
schedulePtr_.reset
(
new List<labelPair>
(
IndirectList<labelPair>(allComms, mySchedule)
)
);
return IndirectList<labelPair>(allComms, mySchedule);
//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 * * * * * * * * * * * * * * //
//- Construct from components
......@@ -257,13 +271,4 @@ Foam::mapDistribute::mapDistribute
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
// ************************************************************************* //
......@@ -36,6 +36,8 @@ Note:
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.
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
......@@ -80,8 +82,6 @@ class mapDistribute
// Private Member Functions
void calcSchedule() const;
//- Disallow default bitwise copy construct
mapDistribute(const mapDistribute&);
......@@ -142,15 +142,15 @@ public:
return constructMap_;
}
//- Calculate a schedule. See above.
static List<labelPair> schedule
(
const labelListList& subMap,
const labelListList& constructMap
);
//- Return a schedule. Demand driven. See above.
const List<labelPair>& schedule() const
{
if (!schedulePtr_.valid())
{
calcSchedule();
}
return schedulePtr_();
}
const List<labelPair>& schedule() const;
// Other
......
......@@ -48,15 +48,28 @@ void Foam::mapDistribute::distribute
// Send sub field to neighbour
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);
toNbr << IndirectList<T>(field, subMap[domain])();
toNbr << subField;
}
}
// 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)
const labelList& map = constructMap[Pstream::myProcNo()];
......@@ -71,7 +84,11 @@ void Foam::mapDistribute::distribute
// Receive sub field from neighbour
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);
List<T> subField(fromNbr);
......@@ -93,7 +110,13 @@ void Foam::mapDistribute::distribute
List<T> newField(constructSize);
// 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)
const labelList& map = constructMap[Pstream::myProcNo()];
......@@ -112,8 +135,16 @@ void Foam::mapDistribute::distribute
if (Pstream::myProcNo() == sendProc)
{
// 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);
toNbr << IndirectList<T>(field, subMap[recvProc])();
toNbr << subField;
}
else
{
......@@ -136,7 +167,13 @@ void Foam::mapDistribute::distribute
List<T> newField(constructSize);
// 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)
const labelList& map = constructMap[Pstream::myProcNo()];
......@@ -149,10 +186,19 @@ void Foam::mapDistribute::distribute
// Send sub field to neighbour
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);
toNbr << IndirectList<T>(field, subMap[domain])();
toNbr << subField;
}
}
......@@ -160,13 +206,13 @@ void Foam::mapDistribute::distribute
// Receive sub field from neighbour
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);
List<T> subField(fromNbr);
const labelList& map = constructMap[domain];
forAll(map, i)
{
newField[map[i]] = subField[i];
......
......@@ -25,7 +25,6 @@ License
\*---------------------------------------------------------------------------*/
#include "coupledPolyPatch.H"
#include "SortableList.H"
#include "ListOps.H"
#include "transform.H"
#include "OFstream.H"
......
......@@ -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
template
<
......
......@@ -235,6 +235,14 @@ public:
const Field<PointType>& points
);
//- Construct from components, reuse storage
PrimitivePatch
(
FaceList<Face>& faces,
Field<PointType>& points,
const bool reUse
);
//- Construct as copy
PrimitivePatch
(
......
......@@ -467,7 +467,8 @@ const edgeList& primitiveMesh::edges() const
{
if (!edgesPtr_)
{
calcEdges(true);
//calcEdges(true);
calcEdges(false);
}
return *edgesPtr_;
......@@ -477,10 +478,8 @@ const labelListList& primitiveMesh::pointEdges() const
{
if (!pePtr_)
{
//// Invert edges
//pePtr_ = new labelListList(nPoints());
//invertManyToMany(nPoints(), edges(), *pePtr_);
calcEdges(true);
//calcEdges(true);
calcEdges(false);
}
return *pePtr_;
......@@ -491,12 +490,53 @@ const labelListList& primitiveMesh::faceEdges() const
{
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_;
}
void primitiveMesh::clearOutEdges()
{
deleteDemandDrivenData(edgesPtr_);
......
......@@ -41,8 +41,7 @@ extern "C"
# include "parmetis.h"
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
......@@ -57,6 +56,8 @@ namespace Foam
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
//- Does prevention of 0 cell domains and calls parmetis.
Foam::label Foam::parMetisDecomp::decompose
(
......@@ -76,6 +77,16 @@ Foam::label Foam::parMetisDecomp::decompose
// Number of dimensions
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
List<int> nLocalCells(Pstream::nProcs());
nLocalCells[Pstream::myProcNo()] = xadj.size()-1;
......@@ -106,12 +117,12 @@ Foam::label Foam::parMetisDecomp::decompose
// Make sure every domain has at least one cell
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// (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.
// Number of cells to send down (is same as number of cells next processor
// has to receive)
// Number of cells to send to the next processor
// (is same as number of cells next processor has to receive)
List<int> nSendCells(Pstream::nProcs(), 0);
for (label procI = nLocalCells.size()-1; procI >=1; procI--)
......@@ -135,6 +146,15 @@ Foam::label Foam::parMetisDecomp::decompose
Field<int> prevCellWeights(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
prepend(prevAdjncy, adjncy);
// 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
int wgtFlag = 0;
int* vwgtPtr = NULL;
......@@ -292,6 +320,15 @@ Foam::label Foam::parMetisDecomp::decompose
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);
}
......
......@@ -24,7 +24,6 @@ License
\*---------------------------------------------------------------------------*/
#include "SortableList.H"
#include "dynamicRefineFvMesh.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
......@@ -32,7 +31,6 @@ License
#include "surfaceFields.H"
#include "fvCFD.H"
#include "syncTools.H"
#include "ListListOps.H"
#include "pointFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
......@@ -399,7 +399,7 @@ bool Foam::octreeDataFaceList::overlaps
const treeBoundBox& sampleBb
) const
{
return sampleBb.intersects(allBb_[index]);
return sampleBb.overlaps(allBb_[index]);
}