Commit e716b6e1 authored by mattijs's avatar mattijs
Browse files

on-the-fly addressing

parent 31d2b569
......@@ -66,6 +66,9 @@ primitiveMesh::primitiveMesh()
ppPtr_(NULL),
cpPtr_(NULL),
allocSize_(0),
labels_(0),
cellCentresPtr_(NULL),
faceCentresPtr_(NULL),
cellVolumesPtr_(NULL),
......@@ -106,6 +109,9 @@ primitiveMesh::primitiveMesh
ppPtr_(NULL),
cpPtr_(NULL),
allocSize_(0),
labels_(0),
cellCentresPtr_(NULL),
faceCentresPtr_(NULL),
cellVolumesPtr_(NULL),
......
......@@ -155,6 +155,17 @@ class primitiveMesh
mutable labelListList* cpPtr_;
// On-the-fly edge addresing storage
//- Temporary storage for addressing. allocSize is the real size
// of the labelList.
mutable label allocSize_;
mutable labelList labels_;
//- Temporary storage for addressing
mutable labelHashSet labelSet_;
// Geometric data
//- Cell centres
......@@ -209,8 +220,14 @@ class primitiveMesh
(
List<DynamicList<label> >&,
DynamicList<edge>&,
const label pA,
const label pB
const label,
const label
);
//- For on-the-fly addressing calculation
static label findFirstCommonElementFromSortedLists
(
const labelList&,
const labelList&
);
......@@ -667,6 +684,55 @@ public:
//- Print a list of all the currently allocated mesh data
void printAllocated() const;
// Per storage whether allocated
inline bool hasCellShapes() const;
inline bool hasEdges() const;
inline bool hasCellCells() const;
inline bool hasEdgeCells() const;
inline bool hasPointCells() const;
inline bool hasCells() const;
inline bool hasEdgeFaces() const;
inline bool hasPointFaces() const;
inline bool hasCellEdges() const;
inline bool hasFaceEdges() const;
inline bool hasPointEdges() const;
inline bool hasPointPoints() const;
inline bool hasCellPoints() const;
inline bool hasCellCentres() const;
inline bool hasFaceCentres() const;
inline bool hasCellVolumes() const;
inline bool hasFaceAreas() const;
// On-the-fly addressing calculation. These functions return either
// a reference to the full addressing (if already calculated) or
// a reference to member data labels_ so be careful when not storing
// result.
//- cellCells using cells
const labelList& cellCells(const label cellI) const;
//- cellPoints using cells
const labelList& cellPoints(const label cellI) const;
//- pointCells using pointFaces
const labelList& pointCells(const label pointI) const;
//- pointPoints using edges, pointEdges
const labelList& pointPoints(const label pointI) const;
//- faceEdges using pointFaces, edges, pointEdges
const labelList& faceEdges(const label faceI) const;
//- edgeFaces using pointFaces, edges, pointEdges
const labelList& edgeFaces(const label edgeI) const;
//- edgeCells using pointFaces, edges, pointEdges
const labelList& edgeCells(const label edgeI) const;
//- cellEdges using cells, pointFaces, edges, pointEdges
const labelList& cellEdges(const label cellI) const;
//- Clear geometry
void clearGeom();
......
......@@ -105,6 +105,53 @@ const labelListList& primitiveMesh::cellCells() const
}
const labelList& primitiveMesh::cellCells(const label cellI) const
{
if (hasCellCells())
{
return cellCells()[cellI];
}
else
{
const labelList& own = faceOwner();
const labelList& nei = faceNeighbour();
const cell& cFaces = cells()[cellI];
labels_.size() = allocSize_;
if (cFaces.size() > allocSize_)
{
labels_.clear();
allocSize_ = cFaces.size();
labels_.setSize(allocSize_);
}
label n = 0;
forAll(cFaces, i)
{
label faceI = cFaces[i];
if (faceI < nInternalFaces())
{
if (own[faceI] == cellI)
{
labels_[n++] = nei[faceI];
}
else
{
labels_[n++] = own[faceI];
}
}
}
labels_.size() = n;
return labels_;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
......
......@@ -53,6 +53,52 @@ const labelListList& primitiveMesh::cellPoints() const
}
const labelList& primitiveMesh::cellPoints(const label cellI) const
{
if (hasCellPoints())
{
return cellPoints()[cellI];
}
else
{
const faceList& fcs = faces();
const labelList& cFaces = cells()[cellI];
labelSet_.clear();
forAll(cFaces, i)
{
const labelList& f = fcs[cFaces[i]];
forAll(f, fp)
{
labelSet_.insert(f[fp]);
}
}
labels_.size() = allocSize_;
if (labelSet_.size() > allocSize_)
{
labels_.clear();
allocSize_ = labelSet_.size();
labels_.setSize(allocSize_);
}
label n = 0;
forAllConstIter(labelHashSet, labelSet_, iter)
{
labels_[n++] = iter.key();
}
labels_.size() = n;
return labels_;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
......
......@@ -771,11 +771,12 @@ bool primitiveMesh::checkPoints
}
}
const labelListList& pc = pointCells();
forAll (pc, pointI)
forAll (pf, pointI)
{
if (pc[pointI].size() == 0)
const labelList& pc = pointCells(pointI);
if (pc.size() == 0)
{
if (setPtr)
{
......
......@@ -51,6 +51,86 @@ const labelListList& primitiveMesh::edgeCells() const
}
const labelList& primitiveMesh::edgeCells(const label edgeI) const
{
if (hasEdgeCells())
{
return edgeCells()[edgeI];
}
else
{
const labelList& own = faceOwner();
const labelList& nei = faceNeighbour();
// edge faces can either return labels_ or reference in edgeLabels.
labelList labelsCopy;
if (!hasEdgeFaces())
{
labelsCopy = edgeFaces(edgeI);
}
const labelList& eFaces =
(
hasEdgeFaces()
? edgeFaces()[edgeI]
: labelsCopy
);
labels_.size() = allocSize_;
// labels_ should certainly be big enough for edge cells.
label n = 0;
// Do quadratic insertion.
forAll(eFaces, i)
{
label faceI = eFaces[i];
{
label ownCellI = own[faceI];
// Check if not already in labels_
for (label j = 0; j < n; j++)
{
if (labels_[j] == ownCellI)
{
ownCellI = -1;
break;
}
}
if (ownCellI != -1)
{
labels_[n++] = ownCellI;
}
}
if (isInternalFace(faceI))
{
label neiCellI = nei[faceI];
for (label j = 0; j < n; j++)
{
if (labels_[j] == neiCellI)
{
neiCellI = -1;
break;
}
}
if (neiCellI != -1)
{
labels_[n++] = neiCellI;
}
}
}
labels_.size() = n;
return labels_;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
......@@ -51,6 +51,59 @@ const labelListList& primitiveMesh::edgeFaces() const
return *efPtr_;
}
const labelList& primitiveMesh::edgeFaces(const label edgeI) const
{
if (hasEdgeFaces())
{
return edgeFaces()[edgeI];
}
else
{
// Use the fact that pointEdges are sorted in incrementing edge order
const edge& e = edges()[edgeI];
const labelList& pFaces0 = pointFaces()[e[0]];
const labelList& pFaces1 = pointFaces()[e[1]];
label i0 = 0;
label i1 = 0;
label n = 0;
labels_.size() = allocSize_;
while (i0 < pFaces0.size() && i1 < pFaces1.size())
{
if (pFaces0[i0] < pFaces1[i1])
{
++i0;
}
else if (pFaces0[i0] > pFaces1[i1])
{
++i1;
}
else
{
// Equal. Append.
if (n == allocSize_)
{
// Have setSize copy contents so far
labels_.size() = n;
allocSize_ = allocSize_*2 + 1;
labels_.setSize(allocSize_);
}
labels_[n++] = pFaces0[i0];
++i0;
++i1;
}
}
labels_.size() = n;
return labels_;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
......
......@@ -461,6 +461,46 @@ void primitiveMesh::calcEdges(const bool doFaceEdges) const
}
label primitiveMesh::findFirstCommonElementFromSortedLists
(
const labelList& list1,
const labelList& list2
)
{
label result = -1;
labelList::const_iterator iter1 = list1.begin();
labelList::const_iterator iter2 = list2.begin();
while (iter1 != list1.end() && iter2 != list2.end())
{
if( *iter1 < *iter2)
{
++iter1;
}
else if (*iter1 > *iter2)
{
++iter2;
}
else
{
result = *iter1;
break;
}
}
if (result == -1)
{
FatalErrorIn
(
"primitiveMesh::findFirstCommonElementFromSortedLists"
"(const labelList&, const labelList&)"
) << "No common elements in lists " << list1 << " and " << list2
<< abort(FatalError);
}
return result;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const edgeList& primitiveMesh::edges() const
......@@ -542,6 +582,91 @@ void primitiveMesh::clearOutEdges()
deleteDemandDrivenData(edgesPtr_);
deleteDemandDrivenData(pePtr_);
deleteDemandDrivenData(fePtr_);
labels_.clear();
allocSize_ = 0;
}
const labelList& primitiveMesh::faceEdges(const label faceI) const
{
if (hasFaceEdges())
{
return faceEdges()[faceI];
}
else
{
const labelListList& pointEs = pointEdges();
const face& f = faces()[faceI];
labels_.size() = allocSize_;
if (f.size() > allocSize_)
{
labels_.clear();
allocSize_ = f.size();
labels_.setSize(allocSize_);
}
label n = 0;
forAll(f, fp)
{
labels_[n++] = findFirstCommonElementFromSortedLists
(
pointEs[f[fp]],
pointEs[f.nextLabel(fp)]
);
}
labels_.size() = n;
return labels_;
}
}
const labelList& primitiveMesh::cellEdges(const label cellI) const
{
if (hasCellEdges())
{
return cellEdges()[cellI];
}
else
{
const labelList& cFaces = cells()[cellI];
labelSet_.clear();
forAll(cFaces, i)
{
const labelList& fe = faceEdges(cFaces[i]);
forAll(fe, feI)
{
labelSet_.insert(fe[feI]);
}
}
labels_.size() = allocSize_;
if (labelSet_.size() > allocSize_)
{
labels_.clear();
allocSize_ = labelSet_.size();
labels_.setSize(allocSize_);
}
label n =0;
forAllConstIter(labelHashSet, labelSet_, iter)
{
labels_[n++] = iter.key();
}
labels_.size() = n;
return labels_;
}
}
......
......@@ -104,6 +104,108 @@ inline bool primitiveMesh::isInternalFace(const label faceIndex) const
}
inline bool primitiveMesh::hasCellShapes() const
{
return cellShapesPtr_;
}
inline bool primitiveMesh::hasEdges() const
{
return edgesPtr_;
}
inline bool primitiveMesh::hasCellCells() const
{
return ccPtr_;
}
inline bool primitiveMesh::hasEdgeCells() const
{
return ecPtr_;
}
inline bool primitiveMesh::hasPointCells() const
{
return pcPtr_;
}
inline bool primitiveMesh::hasCells() const
{
return cfPtr_;
}
inline bool primitiveMesh::hasEdgeFaces() const
{
return efPtr_;
}
inline bool primitiveMesh::hasPointFaces() const
{
return pfPtr_;
}
inline bool primitiveMesh::hasCellEdges() const
{
return cePtr_;
}
inline bool primitiveMesh::hasFaceEdges() const
{
return fePtr_;
}
inline bool primitiveMesh::hasPointEdges() const
{
return pePtr_;
}
inline bool primitiveMesh::hasPointPoints() const
{
return ppPtr_;
}
inline bool primitiveMesh::hasCellPoints() const
{
return cpPtr_;
}
inline bool primitiveMesh::hasCellCentres() const
{