mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
COMP: localPointRegion: moved to meshTools to break circular dep
This commit is contained in:
@ -53,6 +53,7 @@ $(meshWave)/FaceCellWaveName.C
|
||||
|
||||
|
||||
regionSplit/regionSplit.C
|
||||
regionSplit/localPointRegion.C
|
||||
|
||||
indexedOctree/treeDataEdge.C
|
||||
indexedOctree/treeDataFace.C
|
||||
|
||||
622
src/meshTools/regionSplit/localPointRegion.C
Normal file
622
src/meshTools/regionSplit/localPointRegion.C
Normal file
@ -0,0 +1,622 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "localPointRegion.H"
|
||||
#include "syncTools.H"
|
||||
#include "polyMesh.H"
|
||||
#include "mapPolyMesh.H"
|
||||
#include "globalIndex.H"
|
||||
#include "indirectPrimitivePatch.H"
|
||||
#include "dummyTransform.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
defineTypeNameAndDebug(localPointRegion, 0);
|
||||
|
||||
// Reduction class to get minimum value over face.
|
||||
class minEqOpFace
|
||||
{
|
||||
public:
|
||||
|
||||
void operator()(face& x, const face& y) const
|
||||
{
|
||||
if (x.size())
|
||||
{
|
||||
label j = 0;
|
||||
forAll(x, i)
|
||||
{
|
||||
x[i] = min(x[i], y[j]);
|
||||
|
||||
j = y.rcIndex(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
// Are two lists identical either in forward or in reverse order.
|
||||
bool Foam::localPointRegion::isDuplicate
|
||||
(
|
||||
const face& f0,
|
||||
const face& f1,
|
||||
const bool forward
|
||||
)
|
||||
{
|
||||
label fp1 = findIndex(f1, f0[0]);
|
||||
|
||||
if (fp1 == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
forAll(f0, fp0)
|
||||
{
|
||||
if (f0[fp0] != f1[fp1])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (forward)
|
||||
{
|
||||
fp1 = f1.fcIndex(fp1);
|
||||
}
|
||||
else
|
||||
{
|
||||
fp1 = f1.rcIndex(fp1);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Count regions per point
|
||||
void Foam::localPointRegion::countPointRegions
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const boolList& candidatePoint,
|
||||
const Map<label>& candidateFace,
|
||||
faceList& minRegion
|
||||
)
|
||||
{
|
||||
// Almost all will have only one so only
|
||||
// populate Map if more than one.
|
||||
labelList minPointRegion(mesh.nPoints(), -1);
|
||||
// From global point to local (multi-region) point numbering
|
||||
meshPointMap_.resize(candidateFace.size()/100);
|
||||
// From local (multi-region) point to regions
|
||||
DynamicList<labelList> pointRegions(meshPointMap_.size());
|
||||
|
||||
// From faces with any duplicated point on it to local face
|
||||
meshFaceMap_.resize(meshPointMap_.size());
|
||||
|
||||
forAllConstIter(Map<label>, candidateFace, iter)
|
||||
{
|
||||
label faceI = iter.key();
|
||||
|
||||
if (!mesh.isInternalFace(faceI))
|
||||
{
|
||||
const face& f = mesh.faces()[faceI];
|
||||
|
||||
if (minRegion[faceI].empty())
|
||||
{
|
||||
FatalErrorIn("localPointRegion::countPointRegions(..)")
|
||||
<< "Face from candidateFace without minRegion set." << endl
|
||||
<< "Face:" << faceI << " fc:" << mesh.faceCentres()[faceI]
|
||||
<< " verts:" << f << abort(FatalError);
|
||||
}
|
||||
|
||||
forAll(f, fp)
|
||||
{
|
||||
label pointI = f[fp];
|
||||
|
||||
// Even points which were not candidates for splitting might
|
||||
// be on multiple baffles that are being split so check.
|
||||
|
||||
if (candidatePoint[pointI])
|
||||
{
|
||||
label region = minRegion[faceI][fp];
|
||||
|
||||
if (minPointRegion[pointI] == -1)
|
||||
{
|
||||
minPointRegion[pointI] = region;
|
||||
}
|
||||
else if (minPointRegion[pointI] != region)
|
||||
{
|
||||
// Multiple regions for this point. Add.
|
||||
Map<label>::iterator iter = meshPointMap_.find(pointI);
|
||||
if (iter != meshPointMap_.end())
|
||||
{
|
||||
labelList& regions = pointRegions[iter()];
|
||||
if (findIndex(regions, region) == -1)
|
||||
{
|
||||
label sz = regions.size();
|
||||
regions.setSize(sz+1);
|
||||
regions[sz] = region;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
label localPointI = meshPointMap_.size();
|
||||
meshPointMap_.insert(pointI, localPointI);
|
||||
labelList regions(2);
|
||||
regions[0] = minPointRegion[pointI];
|
||||
regions[1] = region;
|
||||
pointRegions.append(regions);
|
||||
}
|
||||
|
||||
label meshFaceMapI = meshFaceMap_.size();
|
||||
meshFaceMap_.insert(faceI, meshFaceMapI);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
minPointRegion.clear();
|
||||
|
||||
// Add internal faces that use any duplicated point. Can only have one
|
||||
// region!
|
||||
forAllConstIter(Map<label>, candidateFace, iter)
|
||||
{
|
||||
label faceI = iter.key();
|
||||
|
||||
if (mesh.isInternalFace(faceI))
|
||||
{
|
||||
const face& f = mesh.faces()[faceI];
|
||||
|
||||
forAll(f, fp)
|
||||
{
|
||||
// Note: candidatePoint test not really necessary but
|
||||
// speeds up rejection.
|
||||
if (candidatePoint[f[fp]] && meshPointMap_.found(f[fp]))
|
||||
{
|
||||
label meshFaceMapI = meshFaceMap_.size();
|
||||
meshFaceMap_.insert(faceI, meshFaceMapI);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Transfer to member data
|
||||
pointRegions.shrink();
|
||||
pointRegions_.setSize(pointRegions.size());
|
||||
forAll(pointRegions, i)
|
||||
{
|
||||
pointRegions_[i].transfer(pointRegions[i]);
|
||||
}
|
||||
|
||||
// Compact minRegion
|
||||
faceRegions_.setSize(meshFaceMap_.size());
|
||||
forAllConstIter(Map<label>, meshFaceMap_, iter)
|
||||
{
|
||||
faceRegions_[iter()].labelList::transfer(minRegion[iter.key()]);
|
||||
|
||||
//// Print a bit
|
||||
//{
|
||||
// label faceI = iter.key();
|
||||
// const face& f = mesh.faces()[faceI];
|
||||
// Pout<< "Face:" << faceI << " fc:" << mesh.faceCentres()[faceI]
|
||||
// << " verts:" << f << endl;
|
||||
// forAll(f, fp)
|
||||
// {
|
||||
// Pout<< " " << f[fp] << " min:" << faceRegions_[iter()][fp]
|
||||
// << endl;
|
||||
// }
|
||||
// Pout<< endl;
|
||||
//}
|
||||
}
|
||||
|
||||
// Compact region numbering
|
||||
// ? TBD.
|
||||
}
|
||||
|
||||
|
||||
void Foam::localPointRegion::calcPointRegions
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
boolList& candidatePoint
|
||||
)
|
||||
{
|
||||
label nBnd = mesh.nFaces()-mesh.nInternalFaces();
|
||||
const labelList& faceOwner = mesh.faceOwner();
|
||||
const labelList& faceNeighbour = mesh.faceNeighbour();
|
||||
|
||||
|
||||
syncTools::syncPointList
|
||||
(
|
||||
mesh,
|
||||
candidatePoint,
|
||||
orEqOp<bool>(),
|
||||
false // nullValue
|
||||
);
|
||||
|
||||
|
||||
// Mark any face/boundaryFace/cell with a point on a candidate point.
|
||||
// - candidateFace does not necessary have to be a baffle!
|
||||
// - candidateFace is synchronised (since candidatePoint is)
|
||||
Map<label> candidateFace(2*nBnd);
|
||||
label candidateFaceI = 0;
|
||||
|
||||
Map<label> candidateCell(nBnd);
|
||||
label candidateCellI = 0;
|
||||
|
||||
forAll(mesh.faces(), faceI)
|
||||
{
|
||||
const face& f = mesh.faces()[faceI];
|
||||
|
||||
forAll(f, fp)
|
||||
{
|
||||
if (candidatePoint[f[fp]])
|
||||
{
|
||||
// Mark face
|
||||
if (candidateFace.insert(faceI, candidateFaceI))
|
||||
{
|
||||
candidateFaceI++;
|
||||
}
|
||||
|
||||
// Mark cells
|
||||
if (candidateCell.insert(faceOwner[faceI], candidateCellI))
|
||||
{
|
||||
candidateCellI++;
|
||||
}
|
||||
|
||||
if (mesh.isInternalFace(faceI))
|
||||
{
|
||||
label nei = faceNeighbour[faceI];
|
||||
if (candidateCell.insert(nei, candidateCellI))
|
||||
{
|
||||
candidateCellI++;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Get global indices for cells
|
||||
globalIndex globalCells(mesh.nCells());
|
||||
|
||||
|
||||
// Determine for every candidate face per point the minimum region
|
||||
// (global cell) it is connected to. (candidateFaces are the
|
||||
// only ones using a
|
||||
// candidate point so the only ones that can be affected)
|
||||
faceList minRegion(mesh.nFaces());
|
||||
forAllConstIter(Map<label>, candidateFace, iter)
|
||||
{
|
||||
label faceI = iter.key();
|
||||
const face& f = mesh.faces()[faceI];
|
||||
|
||||
if (mesh.isInternalFace(faceI))
|
||||
{
|
||||
label globOwn = globalCells.toGlobal(faceOwner[faceI]);
|
||||
label globNei = globalCells.toGlobal(faceNeighbour[faceI]);
|
||||
minRegion[faceI].setSize(f.size(), min(globOwn, globNei));
|
||||
}
|
||||
else
|
||||
{
|
||||
label globOwn = globalCells.toGlobal(faceOwner[faceI]);
|
||||
minRegion[faceI].setSize(f.size(), globOwn);
|
||||
}
|
||||
}
|
||||
|
||||
// Now minimize over all faces that are connected through internal
|
||||
// faces or through cells. This loop iterates over the max number of
|
||||
// cells connected to a point (=8 for hex mesh)
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Transport minimum from face across cell
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Map<label> minPointValue(100);
|
||||
label nChanged = 0;
|
||||
forAllConstIter(Map<label>, candidateCell, iter)
|
||||
{
|
||||
minPointValue.clear();
|
||||
|
||||
label cellI = iter.key();
|
||||
const cell& cFaces = mesh.cells()[cellI];
|
||||
|
||||
// Determine minimum per point
|
||||
forAll(cFaces, cFaceI)
|
||||
{
|
||||
label faceI = cFaces[cFaceI];
|
||||
|
||||
if (minRegion[faceI].size())
|
||||
{
|
||||
const face& f = mesh.faces()[faceI];
|
||||
|
||||
forAll(f, fp)
|
||||
{
|
||||
label pointI = f[fp];
|
||||
Map<label>::iterator iter = minPointValue.find(pointI);
|
||||
|
||||
if (iter == minPointValue.end())
|
||||
{
|
||||
minPointValue.insert(pointI, minRegion[faceI][fp]);
|
||||
}
|
||||
else
|
||||
{
|
||||
label currentMin = iter();
|
||||
iter() = min(currentMin, minRegion[faceI][fp]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set face minimum from point minimum
|
||||
forAll(cFaces, cFaceI)
|
||||
{
|
||||
label faceI = cFaces[cFaceI];
|
||||
|
||||
if (minRegion[faceI].size())
|
||||
{
|
||||
const face& f = mesh.faces()[faceI];
|
||||
|
||||
forAll(f, fp)
|
||||
{
|
||||
label minVal = minPointValue[f[fp]];
|
||||
|
||||
if (minVal != minRegion[faceI][fp])
|
||||
{
|
||||
minRegion[faceI][fp] = minVal;
|
||||
nChanged++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Pout<< "nChanged:" << nChanged << endl;
|
||||
|
||||
if (returnReduce(nChanged, sumOp<label>()) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Transport minimum across coupled faces
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
SubList<face> l
|
||||
(
|
||||
minRegion,
|
||||
mesh.nFaces()-mesh.nInternalFaces(),
|
||||
mesh.nInternalFaces()
|
||||
);
|
||||
syncTools::syncBoundaryFaceList
|
||||
(
|
||||
mesh,
|
||||
l,
|
||||
minEqOpFace(),
|
||||
Foam::dummyTransform() // dummy transformation
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Count regions per point
|
||||
countPointRegions(mesh, candidatePoint, candidateFace, minRegion);
|
||||
minRegion.clear();
|
||||
|
||||
|
||||
//// Print points with multiple regions. These points need to be duplicated.
|
||||
//forAllConstIter(Map<label>, meshPointMap_, iter)
|
||||
//{
|
||||
// Pout<< "point:" << iter.key()
|
||||
// << " coord:" << mesh.points()[iter.key()]
|
||||
// << " regions:" << pointRegions_[iter()] << endl;
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::localPointRegion::localPointRegion(const polyMesh& mesh)
|
||||
:
|
||||
//nRegions_(0),
|
||||
meshPointMap_(0),
|
||||
pointRegions_(0),
|
||||
meshFaceMap_(0),
|
||||
faceRegions_(0)
|
||||
{
|
||||
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||
|
||||
// Get any point on the outside which is on a non-coupled boundary
|
||||
boolList candidatePoint(mesh.nPoints(), false);
|
||||
|
||||
forAll(patches, patchI)
|
||||
{
|
||||
if (!patches[patchI].coupled())
|
||||
{
|
||||
const polyPatch& pp = patches[patchI];
|
||||
|
||||
forAll(pp.meshPoints(), i)
|
||||
{
|
||||
candidatePoint[pp.meshPoints()[i]] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
calcPointRegions(mesh, candidatePoint);
|
||||
}
|
||||
|
||||
|
||||
Foam::localPointRegion::localPointRegion
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const labelList& candidatePoints
|
||||
)
|
||||
:
|
||||
//nRegions_(0),
|
||||
meshPointMap_(0),
|
||||
pointRegions_(0),
|
||||
meshFaceMap_(0),
|
||||
faceRegions_(0)
|
||||
{
|
||||
boolList candidatePoint(mesh.nPoints(), false);
|
||||
|
||||
forAll(candidatePoints, i)
|
||||
{
|
||||
candidatePoint[candidatePoints[i]] = true;
|
||||
}
|
||||
|
||||
calcPointRegions(mesh, candidatePoint);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
// Return a list (in allPatch indices) with either -1 or the face label
|
||||
// of the face that uses the same vertices.
|
||||
Foam::labelList Foam::localPointRegion::findDuplicateFaces
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const labelList& boundaryFaces
|
||||
)
|
||||
{
|
||||
// Addressing engine for all boundary faces.
|
||||
indirectPrimitivePatch allPatch
|
||||
(
|
||||
IndirectList<face>(mesh.faces(), boundaryFaces),
|
||||
mesh.points()
|
||||
);
|
||||
|
||||
labelList duplicateFace(allPatch.size(), -1);
|
||||
label nDuplicateFaces = 0;
|
||||
|
||||
// Find all duplicate faces.
|
||||
forAll(allPatch, bFaceI)
|
||||
{
|
||||
const face& f = allPatch.localFaces()[bFaceI];
|
||||
|
||||
// Get faces connected to f[0].
|
||||
// Check whether share all points with f.
|
||||
const labelList& pFaces = allPatch.pointFaces()[f[0]];
|
||||
|
||||
forAll(pFaces, i)
|
||||
{
|
||||
label otherFaceI = pFaces[i];
|
||||
|
||||
if (otherFaceI > bFaceI)
|
||||
{
|
||||
const face& otherF = allPatch.localFaces()[otherFaceI];
|
||||
|
||||
if (isDuplicate(f, otherF, true))
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"findDuplicateFaces(const primitiveMesh&"
|
||||
", const labelList&)"
|
||||
) << "Face:" << bFaceI + mesh.nInternalFaces()
|
||||
<< " has local points:" << f
|
||||
<< " which are in same order as face:"
|
||||
<< otherFaceI + mesh.nInternalFaces()
|
||||
<< " with local points:" << otherF
|
||||
<< abort(FatalError);
|
||||
}
|
||||
else if (isDuplicate(f, otherF, false))
|
||||
{
|
||||
label meshFace0 = bFaceI + mesh.nInternalFaces();
|
||||
label meshFace1 = otherFaceI + mesh.nInternalFaces();
|
||||
|
||||
if
|
||||
(
|
||||
duplicateFace[bFaceI] != -1
|
||||
|| duplicateFace[otherFaceI] != -1
|
||||
)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"findDuplicateFaces(const primitiveMesh&"
|
||||
", const labelList&)"
|
||||
) << "One of two duplicate faces already marked"
|
||||
<< " as duplicate." << nl
|
||||
<< "This means that three or more faces share"
|
||||
<< " the same points and this is illegal." << nl
|
||||
<< "Face:" << meshFace0
|
||||
<< " with local points:" << f
|
||||
<< " which are in same order as face:"
|
||||
<< meshFace1
|
||||
<< " with local points:" << otherF
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
duplicateFace[bFaceI] = otherFaceI;
|
||||
duplicateFace[otherFaceI] = bFaceI;
|
||||
nDuplicateFaces++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return duplicateFace;
|
||||
}
|
||||
|
||||
|
||||
void Foam::localPointRegion::updateMesh(const mapPolyMesh& map)
|
||||
{
|
||||
{
|
||||
Map<label> newMap(meshFaceMap_.size());
|
||||
|
||||
forAllConstIter(Map<label>, meshFaceMap_, iter)
|
||||
{
|
||||
label newFaceI = map.reverseFaceMap()[iter.key()];
|
||||
|
||||
if (newFaceI >= 0)
|
||||
{
|
||||
newMap.insert(newFaceI, iter());
|
||||
}
|
||||
}
|
||||
meshFaceMap_.transfer(newMap);
|
||||
}
|
||||
{
|
||||
Map<label> newMap(meshPointMap_.size());
|
||||
|
||||
forAllConstIter(Map<label>, meshPointMap_, iter)
|
||||
{
|
||||
label newPointI = map.reversePointMap()[iter.key()];
|
||||
|
||||
if (newPointI >= 0)
|
||||
{
|
||||
newMap.insert(newPointI, iter());
|
||||
}
|
||||
}
|
||||
|
||||
meshPointMap_.transfer(newMap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
201
src/meshTools/regionSplit/localPointRegion.H
Normal file
201
src/meshTools/regionSplit/localPointRegion.H
Normal file
@ -0,0 +1,201 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::localPointRegion
|
||||
|
||||
Description
|
||||
Takes mesh with 'baffles' (= boundary faces sharing points).
|
||||
Determines for selected points on boundary faces the 'point region' it is
|
||||
connected to. Each region can be visited by a cell-face-cell walk.
|
||||
Used in duplicating points after splitting baffles.
|
||||
|
||||
Regions are not consecutive per processor. They will be -1..nRegions_.
|
||||
|
||||
Note: coupled boundaries (cyclics, parallel) not fully tested.
|
||||
|
||||
SourceFiles
|
||||
localPointRegion.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef localPointRegion_H
|
||||
#define localPointRegion_H
|
||||
|
||||
#include "typeInfo.H"
|
||||
#include "Map.H"
|
||||
#include "labelList.H"
|
||||
#include "HashSet.H"
|
||||
#include "faceList.H"
|
||||
#include "boolList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of classes
|
||||
class primitiveMesh;
|
||||
class polyMesh;
|
||||
class face;
|
||||
class mapPolyMesh;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class localPointRegion Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class localPointRegion
|
||||
{
|
||||
// Private data
|
||||
|
||||
////- (global) number of regions
|
||||
//label nRegions_;
|
||||
|
||||
//- Per point that is to duplicated to the local index
|
||||
Map<label> meshPointMap_;
|
||||
|
||||
//- Per local point the regions it is in
|
||||
labelListList pointRegions_;
|
||||
|
||||
//- Per face that uses a duplicated point the local index
|
||||
Map<label> meshFaceMap_;
|
||||
|
||||
//- Per face the region of its points
|
||||
faceList faceRegions_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Given minimum cell the points on a face are connected to
|
||||
// determine the points to be duplicated.
|
||||
void countPointRegions
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const boolList& candidatePoint,
|
||||
const Map<label>& candidateFace,
|
||||
faceList& minRegion
|
||||
);
|
||||
|
||||
//- Do all: calculate points that need to be duplicated.
|
||||
void calcPointRegions
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
boolList& candidatePoint
|
||||
);
|
||||
|
||||
|
||||
//- Check if two faces are equal. If forward = false checks f1 in
|
||||
// reverse order.
|
||||
static bool isDuplicate
|
||||
(
|
||||
const face& f0,
|
||||
const face& f1,
|
||||
const bool forward
|
||||
);
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
ClassName("localPointRegion");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from mesh. Assumes all non-coupled boundary points
|
||||
// are candidates for duplication
|
||||
localPointRegion(const polyMesh& mesh);
|
||||
|
||||
//- Construct from mesh and candidate points for duplication
|
||||
localPointRegion
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const labelList& candidatePoints
|
||||
);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Static Member Functions
|
||||
|
||||
//- Helper routine to find baffles (two boundary faces using the
|
||||
// same points but in reverse order)
|
||||
// Gets list of (boundary!) faces to check. Returns labelList
|
||||
// of same size as the input list
|
||||
// with -1 or index of other face in the input list.
|
||||
// Does not handle duplicate faces on both sides of processor patch
|
||||
static labelList findDuplicateFaces
|
||||
(
|
||||
const primitiveMesh&,
|
||||
const labelList&
|
||||
);
|
||||
|
||||
|
||||
// Access
|
||||
|
||||
////- Global number of regions. TBD. regions not compacted yet.
|
||||
//label nRegions() const
|
||||
//{
|
||||
// return nRegions_;
|
||||
//}
|
||||
|
||||
//- Per point that is to be duplicated the local index
|
||||
const Map<label>& meshPointMap() const
|
||||
{
|
||||
return meshPointMap_;
|
||||
}
|
||||
|
||||
//- Per local point the regions it is in
|
||||
const labelListList& pointRegions() const
|
||||
{
|
||||
return pointRegions_;
|
||||
}
|
||||
|
||||
//- Per face that uses a duplicated point the local index
|
||||
const Map<label>& meshFaceMap() const
|
||||
{
|
||||
return meshFaceMap_;
|
||||
}
|
||||
|
||||
//- Per face the region of its points
|
||||
const faceList& faceRegions() const
|
||||
{
|
||||
return faceRegions_;
|
||||
}
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
//- Force recalculation of locally stored data on topological change
|
||||
void updateMesh(const mapPolyMesh&);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user