Add the OpenFOAM source tree
This commit is contained in:
1962
src/dynamicMesh/slidingInterface/coupleSlidingInterface.C
Normal file
1962
src/dynamicMesh/slidingInterface/coupleSlidingInterface.C
Normal file
File diff suppressed because it is too large
Load Diff
430
src/dynamicMesh/slidingInterface/decoupleSlidingInterface.C
Normal file
430
src/dynamicMesh/slidingInterface/decoupleSlidingInterface.C
Normal file
@ -0,0 +1,430 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "slidingInterface.H"
|
||||
#include "polyMesh.H"
|
||||
#include "primitiveMesh.H"
|
||||
#include "polyTopoChange.H"
|
||||
#include "polyTopoChanger.H"
|
||||
#include "polyModifyFace.H"
|
||||
#include "polyModifyPoint.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::slidingInterface::decoupleInterface
|
||||
(
|
||||
polyTopoChange& ref
|
||||
) const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "void slidingInterface::decoupleInterface("
|
||||
<< "polyTopoChange& ref) const : "
|
||||
<< "Decoupling sliding interface " << name() << endl;
|
||||
}
|
||||
|
||||
if (!attached_)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "void slidingInterface::decoupleInterface("
|
||||
<< "polyTopoChange& ref) const : "
|
||||
<< "Interface already decoupled." << endl;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear previous couple
|
||||
clearCouple(ref);
|
||||
|
||||
const polyMesh& mesh = topoChanger().mesh();
|
||||
const faceList& faces = mesh.faces();
|
||||
const cellList& cells = mesh.cells();
|
||||
|
||||
const labelList& own = mesh.faceOwner();
|
||||
const labelList& nei = mesh.faceNeighbour();
|
||||
|
||||
// Master side
|
||||
|
||||
const primitiveFacePatch& masterPatch =
|
||||
mesh.faceZones()[masterFaceZoneID_.index()]();
|
||||
|
||||
const labelList& masterPatchAddr =
|
||||
mesh.faceZones()[masterFaceZoneID_.index()];
|
||||
|
||||
const boolList& masterPatchFlip =
|
||||
mesh.faceZones()[masterFaceZoneID_.index()].flipMap();
|
||||
|
||||
const labelList& masterFc = masterFaceCells();
|
||||
|
||||
// Recover faces in master patch
|
||||
|
||||
forAll(masterPatchAddr, faceI)
|
||||
{
|
||||
// Make a copy of the face and turn it if necessary
|
||||
face newFace = faces[masterPatchAddr[faceI]];
|
||||
|
||||
if (masterPatchFlip[faceI])
|
||||
{
|
||||
newFace.flip();
|
||||
}
|
||||
|
||||
ref.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
newFace, // new face
|
||||
masterPatchAddr[faceI], // master face index
|
||||
masterFc[faceI], // owner
|
||||
-1, // neighbour
|
||||
false, // flux flip
|
||||
masterPatchID_.index(), // patch ID
|
||||
false, // remove from zone
|
||||
masterFaceZoneID_.index(), // zone ID
|
||||
false // zone flip. Face corrected
|
||||
)
|
||||
);
|
||||
|
||||
// Pout<< "Modifying master patch face no "
|
||||
// << masterPatchAddr[faceI]
|
||||
// << " face: " << faces[masterPatchAddr[faceI]]
|
||||
// << " old owner: " << own[masterPatchAddr[faceI]]
|
||||
// << " new owner: " << masterFc[faceI]
|
||||
// << endl;
|
||||
}
|
||||
|
||||
// Slave side
|
||||
|
||||
const primitiveFacePatch& slavePatch =
|
||||
mesh.faceZones()[slaveFaceZoneID_.index()]();
|
||||
|
||||
const labelList& slavePatchAddr =
|
||||
mesh.faceZones()[slaveFaceZoneID_.index()];
|
||||
|
||||
const boolList& slavePatchFlip =
|
||||
mesh.faceZones()[slaveFaceZoneID_.index()].flipMap();
|
||||
|
||||
const labelList& slaveFc = slaveFaceCells();
|
||||
|
||||
// Grab retired point mapping
|
||||
const Map<label>& rpm = retiredPointMap();
|
||||
|
||||
// Recover faces in slave patch
|
||||
|
||||
forAll(slavePatchAddr, faceI)
|
||||
{
|
||||
// Make a copy of face and turn it if necessary
|
||||
face newFace = faces[slavePatchAddr[faceI]];
|
||||
|
||||
if (slavePatchFlip[faceI])
|
||||
{
|
||||
newFace.flip();
|
||||
}
|
||||
|
||||
// Recover retired points on the slave side
|
||||
forAll(newFace, pointI)
|
||||
{
|
||||
Map<label>::const_iterator rpmIter = rpm.find(newFace[pointI]);
|
||||
if (rpmIter != rpm.end())
|
||||
{
|
||||
// Master of retired point; grab its original
|
||||
// Pout<< "Reinstating retired point: " << newFace[pointI]
|
||||
// << " with old: " << rpm.find(newFace[pointI])()
|
||||
// << endl;
|
||||
|
||||
newFace[pointI] = rpmIter();
|
||||
}
|
||||
}
|
||||
|
||||
ref.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
newFace, // new face
|
||||
slavePatchAddr[faceI], // master face index
|
||||
slaveFc[faceI], // owner
|
||||
-1, // neighbour
|
||||
false, // flux flip
|
||||
slavePatchID_.index(), // patch ID
|
||||
false, // remove from zone
|
||||
slaveFaceZoneID_.index(), // zone ID
|
||||
false // zone flip. Face corrected
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Re-create the master stick-out faces
|
||||
|
||||
// Grab the list of faces in the layer
|
||||
const labelList& masterStickOuts = masterStickOutFaces();
|
||||
|
||||
forAll(masterStickOuts, faceI)
|
||||
{
|
||||
// Renumber the face and remove additional points
|
||||
|
||||
const label curFaceID = masterStickOuts[faceI];
|
||||
|
||||
const face& oldFace = faces[curFaceID];
|
||||
|
||||
DynamicList<label> newFaceLabels(oldFace.size());
|
||||
|
||||
bool changed = false;
|
||||
|
||||
forAll(oldFace, pointI)
|
||||
{
|
||||
// Check if the point is removed
|
||||
if (ref.pointRemoved(oldFace[pointI]))
|
||||
{
|
||||
// Point removed; skip it
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
newFaceLabels.append(oldFace[pointI]);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (newFaceLabels.size() < 3)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void slidingInterface::decoupleInterface("
|
||||
"polyTopoChange& ref) const"
|
||||
) << "Face " << curFaceID << " reduced to less than "
|
||||
<< "3 points. Topological/cutting error." << nl
|
||||
<< "Old face: " << oldFace << " new face: " << newFaceLabels
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Get face zone and its flip
|
||||
label modifiedFaceZone = mesh.faceZones().whichZone(curFaceID);
|
||||
bool modifiedFaceZoneFlip = false;
|
||||
|
||||
if (modifiedFaceZone >= 0)
|
||||
{
|
||||
modifiedFaceZoneFlip =
|
||||
mesh.faceZones()[modifiedFaceZone].flipMap()
|
||||
[
|
||||
mesh.faceZones()[modifiedFaceZone].whichFace(curFaceID)
|
||||
];
|
||||
}
|
||||
|
||||
face newFace;
|
||||
newFace.transfer(newFaceLabels);
|
||||
|
||||
// Pout<< "Modifying master stick-out face " << curFaceID
|
||||
// << " old face: " << oldFace
|
||||
// << " new face: " << newFace
|
||||
// << endl;
|
||||
|
||||
// Modify the face
|
||||
ref.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
newFace, // modified face
|
||||
curFaceID, // label of face being modified
|
||||
own[curFaceID], // owner
|
||||
nei[curFaceID], // neighbour
|
||||
false, // face flip
|
||||
mesh.boundaryMesh().whichPatch(curFaceID), // patch for face
|
||||
false, // remove from zone
|
||||
modifiedFaceZone, // zone for face
|
||||
modifiedFaceZoneFlip // face flip in zone
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Re-create the slave stick-out faces
|
||||
|
||||
labelHashSet slaveLayerCellFaceMap
|
||||
(
|
||||
primitiveMesh::facesPerCell_*(masterPatch.size() + slavePatch.size())
|
||||
);
|
||||
|
||||
forAll(slaveFc, faceI)
|
||||
{
|
||||
const labelList& curFaces = cells[slaveFc[faceI]];
|
||||
|
||||
forAll(curFaces, faceI)
|
||||
{
|
||||
// Check if the face belongs to the slave face zone; and
|
||||
// if it has been removed; if not add it
|
||||
if
|
||||
(
|
||||
mesh.faceZones().whichZone(curFaces[faceI])
|
||||
!= slaveFaceZoneID_.index()
|
||||
&& !ref.faceRemoved(curFaces[faceI])
|
||||
|
||||
)
|
||||
{
|
||||
slaveLayerCellFaceMap.insert(curFaces[faceI]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Grab the list of faces in the layer
|
||||
const labelList& slaveStickOuts = slaveStickOutFaces();
|
||||
|
||||
// Grab master point mapping
|
||||
const Map<label>& masterPm = masterPatch.meshPointMap();
|
||||
|
||||
forAll(slaveStickOuts, faceI)
|
||||
{
|
||||
// Renumber the face and remove additional points
|
||||
|
||||
const label curFaceID = slaveStickOuts[faceI];
|
||||
|
||||
const face& oldFace = faces[curFaceID];
|
||||
|
||||
DynamicList<label> newFaceLabels(oldFace.size());
|
||||
|
||||
bool changed = false;
|
||||
|
||||
forAll(oldFace, pointI)
|
||||
{
|
||||
// Check if the point is removed or retired
|
||||
if (rpm.found(oldFace[pointI]))
|
||||
{
|
||||
// Master of retired point; grab its original
|
||||
changed = true;
|
||||
|
||||
// Pout<< "Reinstating retired point: " << oldFace[pointI]
|
||||
// << " with old: " << rpm.find(oldFace[pointI])()
|
||||
// << endl;
|
||||
|
||||
newFaceLabels.append(rpm.find(oldFace[pointI])());
|
||||
}
|
||||
else if (ref.pointRemoved(oldFace[pointI]))
|
||||
{
|
||||
// Point removed; skip it
|
||||
changed = true;
|
||||
}
|
||||
else if (masterPm.found(oldFace[pointI]))
|
||||
{
|
||||
// Point from master patch only; skip it
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
newFaceLabels.append(oldFace[pointI]);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (newFaceLabels.size() < 3)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void slidingInterface::decoupleInterface("
|
||||
"polyTopoChange& ref) const"
|
||||
) << "Face " << curFaceID << " reduced to less than "
|
||||
<< "3 points. Topological/cutting error." << nl
|
||||
<< "Old face: " << oldFace << " new face: " << newFaceLabels
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Get face zone and its flip
|
||||
label modifiedFaceZone = mesh.faceZones().whichZone(curFaceID);
|
||||
bool modifiedFaceZoneFlip = false;
|
||||
|
||||
if (modifiedFaceZone >= 0)
|
||||
{
|
||||
modifiedFaceZoneFlip =
|
||||
mesh.faceZones()[modifiedFaceZone].flipMap()
|
||||
[
|
||||
mesh.faceZones()[modifiedFaceZone].whichFace(curFaceID)
|
||||
];
|
||||
}
|
||||
|
||||
face newFace;
|
||||
newFace.transfer(newFaceLabels);
|
||||
|
||||
// Pout<< "Modifying slave stick-out face " << curFaceID
|
||||
// << " old face: " << oldFace
|
||||
// << " new face: " << newFace
|
||||
// << endl;
|
||||
|
||||
// Modify the face
|
||||
ref.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
newFace, // modified face
|
||||
curFaceID, // label of face being modified
|
||||
own[curFaceID], // owner
|
||||
nei[curFaceID], // neighbour
|
||||
false, // face flip
|
||||
mesh.boundaryMesh().whichPatch(curFaceID), // patch for face
|
||||
false, // remove from zone
|
||||
modifiedFaceZone, // zone for face
|
||||
modifiedFaceZoneFlip // face flip in zone
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Bring all slave patch points back to life
|
||||
const pointField& points = mesh.points();
|
||||
|
||||
const labelList& slaveMeshPoints =
|
||||
mesh.faceZones()[slaveFaceZoneID_.index()]().meshPoints();
|
||||
|
||||
forAll(slaveMeshPoints, pointI)
|
||||
{
|
||||
ref.setAction
|
||||
(
|
||||
polyModifyPoint
|
||||
(
|
||||
slaveMeshPoints[pointI], // point ID
|
||||
points[slaveMeshPoints[pointI]], // point
|
||||
false, // remove from zone
|
||||
mesh.pointZones().whichZone(slaveMeshPoints[pointI]), // zone
|
||||
true // in a cell
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Clear the retired point numbering
|
||||
retiredPointMapPtr_->clear();
|
||||
|
||||
// Finished decoupling
|
||||
attached_ = false;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "void slidingInterface::coupleInterface("
|
||||
<< "polyTopoChange& ref) const : "
|
||||
<< "Finished decoupling sliding interface " << name() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
287
src/dynamicMesh/slidingInterface/enrichedPatch/enrichedPatch.C
Normal file
287
src/dynamicMesh/slidingInterface/enrichedPatch/enrichedPatch.C
Normal file
@ -0,0 +1,287 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "enrichedPatch.H"
|
||||
#include "demandDrivenData.H"
|
||||
#include "OFstream.H"
|
||||
#include "meshTools.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(enrichedPatch, 0);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::enrichedPatch::calcMeshPoints() const
|
||||
{
|
||||
if (meshPointsPtr_)
|
||||
{
|
||||
FatalErrorIn("void enrichedPatch::calcMeshPoints() const")
|
||||
<< "Mesh points already calculated."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
meshPointsPtr_ = new labelList(pointMap().toc());
|
||||
labelList& mp = *meshPointsPtr_;
|
||||
|
||||
sort(mp);
|
||||
}
|
||||
|
||||
|
||||
void Foam::enrichedPatch::calcLocalFaces() const
|
||||
{
|
||||
if (localFacesPtr_)
|
||||
{
|
||||
FatalErrorIn("void enrichedPatch::calcLocalFaces() const")
|
||||
<< "Local faces already calculated."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Invert mesh points and renumber faces using it
|
||||
const labelList& mp = meshPoints();
|
||||
|
||||
Map<label> mpLookup(2*mp.size());
|
||||
|
||||
forAll(mp, mpI)
|
||||
{
|
||||
mpLookup.insert(mp[mpI], mpI);
|
||||
}
|
||||
|
||||
const faceList& faces = enrichedFaces();
|
||||
|
||||
localFacesPtr_ = new faceList(faces.size());
|
||||
faceList& lf = *localFacesPtr_;
|
||||
|
||||
forAll(faces, faceI)
|
||||
{
|
||||
const face& f = faces[faceI];
|
||||
|
||||
face& curlf = lf[faceI];
|
||||
|
||||
curlf.setSize(f.size());
|
||||
|
||||
forAll(f, pointI)
|
||||
{
|
||||
curlf[pointI] = mpLookup.find(f[pointI])();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::enrichedPatch::calcLocalPoints() const
|
||||
{
|
||||
if (localPointsPtr_)
|
||||
{
|
||||
FatalErrorIn("void enrichedPatch::calcLocalPoints() const")
|
||||
<< "Local points already calculated."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
const labelList& mp = meshPoints();
|
||||
|
||||
localPointsPtr_ = new pointField(mp.size());
|
||||
pointField& lp = *localPointsPtr_;
|
||||
|
||||
forAll(lp, i)
|
||||
{
|
||||
lp[i] = pointMap().find(mp[i])();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::enrichedPatch::clearOut()
|
||||
{
|
||||
deleteDemandDrivenData(enrichedFacesPtr_);
|
||||
|
||||
deleteDemandDrivenData(meshPointsPtr_);
|
||||
deleteDemandDrivenData(localFacesPtr_);
|
||||
deleteDemandDrivenData(localPointsPtr_);
|
||||
deleteDemandDrivenData(pointPointsPtr_);
|
||||
deleteDemandDrivenData(masterPointFacesPtr_);
|
||||
|
||||
clearCutFaces();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
// Construct from components
|
||||
Foam::enrichedPatch::enrichedPatch
|
||||
(
|
||||
const primitiveFacePatch& masterPatch,
|
||||
const primitiveFacePatch& slavePatch,
|
||||
const labelList& slavePointPointHits,
|
||||
const labelList& slavePointEdgeHits,
|
||||
const List<objectHit>& slavePointFaceHits
|
||||
)
|
||||
:
|
||||
masterPatch_(masterPatch),
|
||||
slavePatch_(slavePatch),
|
||||
pointMap_
|
||||
(
|
||||
masterPatch_.meshPoints().size()
|
||||
+ slavePatch_.meshPoints().size()
|
||||
),
|
||||
pointMapComplete_(false),
|
||||
pointMergeMap_(2*slavePatch_.meshPoints().size()),
|
||||
slavePointPointHits_(slavePointPointHits),
|
||||
slavePointEdgeHits_(slavePointEdgeHits),
|
||||
slavePointFaceHits_(slavePointFaceHits),
|
||||
enrichedFacesPtr_(NULL),
|
||||
meshPointsPtr_(NULL),
|
||||
localFacesPtr_(NULL),
|
||||
localPointsPtr_(NULL),
|
||||
pointPointsPtr_(NULL),
|
||||
masterPointFacesPtr_(NULL),
|
||||
cutFacesPtr_(NULL),
|
||||
cutFaceMasterPtr_(NULL),
|
||||
cutFaceSlavePtr_(NULL)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::enrichedPatch::~enrichedPatch()
|
||||
{
|
||||
clearOut();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::labelList& Foam::enrichedPatch::meshPoints() const
|
||||
{
|
||||
if (!meshPointsPtr_)
|
||||
{
|
||||
calcMeshPoints();
|
||||
}
|
||||
|
||||
return *meshPointsPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::faceList& Foam::enrichedPatch::localFaces() const
|
||||
{
|
||||
if (!localFacesPtr_)
|
||||
{
|
||||
calcLocalFaces();
|
||||
}
|
||||
|
||||
return *localFacesPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::pointField& Foam::enrichedPatch::localPoints() const
|
||||
{
|
||||
if (!localPointsPtr_)
|
||||
{
|
||||
calcLocalPoints();
|
||||
}
|
||||
|
||||
return *localPointsPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::labelListList& Foam::enrichedPatch::pointPoints() const
|
||||
{
|
||||
if (!pointPointsPtr_)
|
||||
{
|
||||
calcPointPoints();
|
||||
}
|
||||
|
||||
return *pointPointsPtr_;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::enrichedPatch::checkSupport() const
|
||||
{
|
||||
const faceList& faces = enrichedFaces();
|
||||
|
||||
bool error = false;
|
||||
|
||||
forAll(faces, faceI)
|
||||
{
|
||||
const face& curFace = faces[faceI];
|
||||
|
||||
forAll(curFace, pointI)
|
||||
{
|
||||
if (!pointMap().found(curFace[pointI]))
|
||||
{
|
||||
WarningIn("void enrichedPatch::checkSupport()")
|
||||
<< "Point " << pointI << " of face " << faceI
|
||||
<< " global point index: " << curFace[pointI]
|
||||
<< " not supported in point map. This is not allowed."
|
||||
<< endl;
|
||||
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
void Foam::enrichedPatch::writeOBJ(const fileName& fName) const
|
||||
{
|
||||
OFstream str(fName);
|
||||
|
||||
const pointField& lp = localPoints();
|
||||
|
||||
forAll(lp, pointI)
|
||||
{
|
||||
meshTools::writeOBJ(str, lp[pointI]);
|
||||
}
|
||||
|
||||
const faceList& faces = localFaces();
|
||||
|
||||
forAll(faces, faceI)
|
||||
{
|
||||
const face& f = faces[faceI];
|
||||
|
||||
str << 'f';
|
||||
forAll(f, fp)
|
||||
{
|
||||
str << ' ' << f[fp]+1;
|
||||
}
|
||||
str << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
293
src/dynamicMesh/slidingInterface/enrichedPatch/enrichedPatch.H
Normal file
293
src/dynamicMesh/slidingInterface/enrichedPatch/enrichedPatch.H
Normal file
@ -0,0 +1,293 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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::enrichedPatch
|
||||
|
||||
Description
|
||||
The enriched patch contains a double set of faces from the two
|
||||
sides of the sliding interface before the cutting.
|
||||
|
||||
The patch basically consists of two over-lapping sets of faces sitting
|
||||
on a common point support, where every edge may be shared by more than
|
||||
2 faces. The patch points are collected in a map. Additional
|
||||
information needed for cutting is the point insertion into every edge
|
||||
of master and slave.
|
||||
|
||||
Note:
|
||||
If new points are created during master-slave edge cutting, they
|
||||
should be registred with the pointMap.
|
||||
|
||||
|
||||
SourceFiles
|
||||
enrichedPatch.C
|
||||
enrichedPatchCutFaces.C
|
||||
enrichedPatchFaces.C
|
||||
enrichedPatchPointMap.C
|
||||
enrichedPatchPointMergeMap.C
|
||||
enrichedPatchPointPoints.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef enrichedPatch_H
|
||||
#define enrichedPatch_H
|
||||
|
||||
#include "primitiveFacePatch.H"
|
||||
#include "Map.H"
|
||||
#include "point.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class enrichedPatch Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class enrichedPatch
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Reference to master patch
|
||||
const primitiveFacePatch& masterPatch_;
|
||||
|
||||
//- Reference to slave patch
|
||||
const primitiveFacePatch& slavePatch_;
|
||||
|
||||
//- Map of points supporting patch faces
|
||||
mutable Map<point> pointMap_;
|
||||
|
||||
//- Has the point map been completed?
|
||||
mutable bool pointMapComplete_;
|
||||
|
||||
//- Map of point merges
|
||||
mutable Map<label> pointMergeMap_;
|
||||
|
||||
//- Slave point point hits
|
||||
const labelList& slavePointPointHits_;
|
||||
|
||||
//- Slave point edge hits
|
||||
const labelList& slavePointEdgeHits_;
|
||||
|
||||
//- Slave point face hits
|
||||
const List<objectHit>& slavePointFaceHits_;
|
||||
|
||||
|
||||
// Demand-driven private data
|
||||
|
||||
//- Enriched patch
|
||||
mutable faceList* enrichedFacesPtr_;
|
||||
|
||||
//- Mesh points
|
||||
mutable labelList* meshPointsPtr_;
|
||||
|
||||
//- Local faces
|
||||
mutable faceList* localFacesPtr_;
|
||||
|
||||
//- Local points
|
||||
mutable pointField* localPointsPtr_;
|
||||
|
||||
//- Point-point addressing
|
||||
mutable labelListList* pointPointsPtr_;
|
||||
|
||||
// Master point addressing
|
||||
mutable Map<labelList>* masterPointFacesPtr_;
|
||||
|
||||
|
||||
// Cut faces and addressing
|
||||
|
||||
//- Cut faces
|
||||
mutable faceList* cutFacesPtr_;
|
||||
|
||||
//- Cut face master
|
||||
// - the face on the master patch for internal faces
|
||||
// - the creator face for boundary face
|
||||
mutable labelList* cutFaceMasterPtr_;
|
||||
|
||||
//- Cut face slave
|
||||
// - the face on the slave patch for internal faces
|
||||
// - -1 for boundary face
|
||||
mutable labelList* cutFaceSlavePtr_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
enrichedPatch(const enrichedPatch&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const enrichedPatch&);
|
||||
|
||||
// Creation of demand-driven private data
|
||||
|
||||
//- Calculate point merge map
|
||||
void calcPointMergeMap() const;
|
||||
|
||||
//- Complete point map
|
||||
void completePointMap() const;
|
||||
|
||||
//- Calculate mesh points
|
||||
void calcMeshPoints() const;
|
||||
|
||||
//- Calculate local points
|
||||
void calcLocalPoints() const;
|
||||
|
||||
//- Calculate local faces
|
||||
void calcLocalFaces() const;
|
||||
|
||||
//- Calculate point-point addressing
|
||||
void calcPointPoints() const;
|
||||
|
||||
//- Calculate master point addressing
|
||||
void calcMasterPointFaces() const;
|
||||
|
||||
//- Calculate cut faces
|
||||
void calcCutFaces() const;
|
||||
|
||||
//- Clear cut faces
|
||||
void clearCutFaces();
|
||||
|
||||
//- Clear out demand-driven data
|
||||
void clearOut();
|
||||
|
||||
|
||||
// Static data members
|
||||
|
||||
//- Estimated ratio of original-to-enriched face size
|
||||
static const label enrichedFaceRatio_;
|
||||
|
||||
//- Estimated number of master face hits by slave points
|
||||
static const label nFaceHits_;
|
||||
|
||||
//- Size of face on which the check is forced
|
||||
static const label maxFaceSizeDebug_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Static data members
|
||||
ClassName("enrichedPatch");
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
enrichedPatch
|
||||
(
|
||||
const primitiveFacePatch& masterPatch,
|
||||
const primitiveFacePatch& slavePatch,
|
||||
const labelList& slavePointPointHits,
|
||||
// -1 or common point snapped to
|
||||
const labelList& slavePointEdgeHits,
|
||||
// -1 or common edge snapped to
|
||||
const List<objectHit>& slavePointFaceHits
|
||||
// master face snapped to
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
~enrichedPatch();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return non-const access to point map to add points
|
||||
Map<point>& pointMap();
|
||||
|
||||
//- Return map of points
|
||||
const Map<point>& pointMap() const;
|
||||
|
||||
//- Return map of point merges
|
||||
Map<label>& pointMergeMap()
|
||||
{
|
||||
return pointMergeMap_;
|
||||
}
|
||||
|
||||
//- Return map of point merges
|
||||
const Map<label>& pointMergeMap() const
|
||||
{
|
||||
return pointMergeMap_;
|
||||
}
|
||||
|
||||
|
||||
// Topological data
|
||||
|
||||
//- Calculate enriched faces
|
||||
void calcEnrichedFaces
|
||||
(
|
||||
const labelListList& pointsIntoMasterEdges,
|
||||
const labelListList& pointsIntoSlaveEdges,
|
||||
const pointField& projectedSlavePoints
|
||||
);
|
||||
|
||||
//- Return enriched faces
|
||||
const faceList& enrichedFaces() const;
|
||||
|
||||
//- Return mesh points
|
||||
const labelList& meshPoints() const;
|
||||
|
||||
//- Return local faces
|
||||
const faceList& localFaces() const;
|
||||
|
||||
//- Return local points
|
||||
const pointField& localPoints() const;
|
||||
|
||||
//- Return point-point addressing
|
||||
const labelListList& pointPoints() const;
|
||||
|
||||
//- Master point face addressing
|
||||
const Map<labelList>& masterPointFaces() const;
|
||||
|
||||
|
||||
// Cut faces
|
||||
|
||||
//- Return list of cut faces
|
||||
const faceList& cutFaces() const;
|
||||
|
||||
//- Return cut face master list
|
||||
const labelList& cutFaceMaster() const;
|
||||
|
||||
//- Return cut face slave list
|
||||
const labelList& cutFaceSlave() const;
|
||||
|
||||
|
||||
//- Check if the patch is fully supported
|
||||
bool checkSupport() const;
|
||||
|
||||
|
||||
//- Debugging: dump graphical representation to obj format file
|
||||
void writeOBJ(const fileName&) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,709 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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/>.
|
||||
|
||||
Description
|
||||
Calculating cut faces of the enriched patch, together with the addressing
|
||||
into master and slave patch.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "enrichedPatch.H"
|
||||
#include "boolList.H"
|
||||
#include "DynamicList.H"
|
||||
#include "labelPair.H"
|
||||
#include "primitiveMesh.H"
|
||||
#include "HashSet.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
// If the cut face gets more than this number of points, it will be checked
|
||||
const Foam::label Foam::enrichedPatch::maxFaceSizeDebug_ = 100;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
// Index of debug signs:
|
||||
// x - skip a point
|
||||
// l - left turn
|
||||
// r - right turn
|
||||
|
||||
void Foam::enrichedPatch::calcCutFaces() const
|
||||
{
|
||||
if (cutFacesPtr_ || cutFaceMasterPtr_ || cutFaceSlavePtr_)
|
||||
{
|
||||
FatalErrorIn("void enrichedPatch::calcCutFaces() const")
|
||||
<< "Cut faces addressing already calculated."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
const faceList& enFaces = enrichedFaces();
|
||||
const labelList& mp = meshPoints();
|
||||
const faceList& lf = localFaces();
|
||||
const pointField& lp = localPoints();
|
||||
const labelListList& pp = pointPoints();
|
||||
// Pout<< "enFaces: " << enFaces << endl;
|
||||
// Pout<< "lf: " << lf << endl;
|
||||
// Pout<< "lp: " << lp << endl;
|
||||
// Pout<< "pp: " << pp << endl;
|
||||
const Map<labelList>& masterPointFaceAddr = masterPointFaces();
|
||||
|
||||
// Prepare the storage
|
||||
DynamicList<face> cf(2*lf.size());
|
||||
DynamicList<label> cfMaster(2*lf.size());
|
||||
DynamicList<label> cfSlave(2*lf.size());
|
||||
|
||||
// Algorithm
|
||||
// Go through all the faces
|
||||
// 1) For each face, start at point zero and grab the edge zero.
|
||||
// Both points are added into the cut face. Mark the first edge
|
||||
// as used and position the current point as the end of the first
|
||||
// edge and previous point as point zero.
|
||||
// 2) Grab all possible points from the current point. Excluding
|
||||
// the previous point find the point giving the biggest right
|
||||
// turn. Add the point to the face and mark the edges as used.
|
||||
// Continue doing this until the face is complete, i.e. the next point
|
||||
// to add is the first point of the face.
|
||||
// 3) Once the facet is completed, register its owner from the face
|
||||
// it has been created from (remember that the first lot of faces
|
||||
// inserted into the enriched faces list are the slaves, to allow
|
||||
// matching of the other side).
|
||||
// 4) If the facet is created from an original slave face, go
|
||||
// through the master patch and try to identify the master face
|
||||
// this facet belongs to. This is recognised by the fact that the
|
||||
// faces consists exclusively of the points of the master face and
|
||||
// the points projected onto the face.
|
||||
|
||||
// Create a set of edge usage parameters
|
||||
HashSet<edge, Hash<edge> > edgesUsedOnce(pp.size());
|
||||
HashSet<edge, Hash<edge> > edgesUsedTwice
|
||||
(pp.size()*primitiveMesh::edgesPerPoint_);
|
||||
|
||||
|
||||
forAll(lf, faceI)
|
||||
{
|
||||
const face& curLocalFace = lf[faceI];
|
||||
const face& curGlobalFace = enFaces[faceI];
|
||||
|
||||
// Pout<< "Doing face " << faceI
|
||||
// << " local: " << curLocalFace
|
||||
// << " or " << curGlobalFace
|
||||
// << endl;
|
||||
|
||||
// if (faceI < slavePatch_.size())
|
||||
// {
|
||||
// Pout<< "original slave: " << slavePatch_[faceI]
|
||||
// << " local: " << slavePatch_.localFaces()[faceI] << endl;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Pout<< "original master: "
|
||||
// << masterPatch_[faceI - slavePatch_.size()] << " "
|
||||
// << masterPatch_.localFaces()[faceI - slavePatch_.size()]
|
||||
// << endl;
|
||||
// }
|
||||
// {
|
||||
// pointField facePoints = curLocalFace.points(lp);
|
||||
// forAll(curLocalFace, pointI)
|
||||
// {
|
||||
// Pout<< "v " << facePoints[pointI].x() << " "
|
||||
// << facePoints[pointI].y() << " "
|
||||
// << facePoints[pointI].z() << endl;
|
||||
// }
|
||||
// }
|
||||
|
||||
// Track the usage of face edges. When all edges are used, the
|
||||
// face decomposition is complete.
|
||||
// The seed edges include all the edges of the original face + all edges
|
||||
// of other faces that have been used in the construction of the
|
||||
// facet. Edges from other faces can be considered as
|
||||
// internal to the current face if used only once.
|
||||
|
||||
// Track the edge usage to avoid duplicate faces and reset it to unused
|
||||
boolList usedFaceEdges(curLocalFace.size(), false);
|
||||
|
||||
SLList<edge> edgeSeeds;
|
||||
|
||||
// Insert the edges of current face into the seed list.
|
||||
edgeList cfe = curLocalFace.edges();
|
||||
forAll(curLocalFace, edgeI)
|
||||
{
|
||||
edgeSeeds.append(cfe[edgeI]);
|
||||
}
|
||||
|
||||
// Grab face normal
|
||||
vector normal = curLocalFace.normal(lp);
|
||||
normal /= mag(normal);
|
||||
|
||||
while (edgeSeeds.size())
|
||||
{
|
||||
// Pout<< "edgeSeeds.size(): "
|
||||
// << edgeSeeds.size()
|
||||
// << endl;
|
||||
|
||||
const edge curEdge = edgeSeeds.removeHead();
|
||||
|
||||
// Locate the edge in current face
|
||||
const label curEdgeWhich = curLocalFace.which(curEdge.start());
|
||||
|
||||
// Check if the edge is in current face and if it has been
|
||||
// used already. If so, skip it
|
||||
if
|
||||
(
|
||||
curEdgeWhich > -1
|
||||
&& curLocalFace.nextLabel(curEdgeWhich) == curEdge.end()
|
||||
)
|
||||
{
|
||||
// Edge is in the starting face.
|
||||
// If unused, mark it as used; if used, skip it
|
||||
if (usedFaceEdges[curEdgeWhich]) continue;
|
||||
|
||||
usedFaceEdges[curEdgeWhich] = true;
|
||||
}
|
||||
|
||||
// If the edge has already been used twice, skip it
|
||||
if (edgesUsedTwice.found(curEdge)) continue;
|
||||
|
||||
// Pout<< "Trying new edge (" << mp[curEdge.start()]
|
||||
// << ", " << mp[curEdge.end()]
|
||||
// << ") seed: " << curEdge
|
||||
// << " used: " << edgesUsedTwice.found(curEdge)
|
||||
// << endl;
|
||||
|
||||
// Estimate the size of cut face as twice the size of original face
|
||||
DynamicList<label> cutFaceGlobalPoints(2*curLocalFace.size());
|
||||
DynamicList<label> cutFaceLocalPoints(2*curLocalFace.size());
|
||||
|
||||
// Found unused edge.
|
||||
label prevPointLabel = curEdge.start();
|
||||
cutFaceGlobalPoints.append(mp[prevPointLabel]);
|
||||
cutFaceLocalPoints.append(prevPointLabel);
|
||||
// Pout<< "prevPointLabel: " << mp[prevPointLabel] << endl;
|
||||
// Grab current point and append it to the list
|
||||
label curPointLabel = curEdge.end();
|
||||
point curPoint = lp[curPointLabel];
|
||||
cutFaceGlobalPoints.append(mp[curPointLabel]);
|
||||
cutFaceLocalPoints.append(curPointLabel);
|
||||
|
||||
bool completedCutFace = false;
|
||||
|
||||
label faceSizeDebug = maxFaceSizeDebug_;
|
||||
|
||||
do
|
||||
{
|
||||
// Grab the next point options
|
||||
|
||||
// Pout<< "curPointLabel: " << mp[curPointLabel] << endl;
|
||||
|
||||
const labelList& nextPoints = pp[curPointLabel];
|
||||
|
||||
// Pout<< "nextPoints: "
|
||||
// << UIndirectList<label>(mp, nextPoints)
|
||||
// << endl;
|
||||
|
||||
// Get the vector along the edge and the right vector
|
||||
vector ahead = curPoint - lp[prevPointLabel];
|
||||
ahead -= normal*(normal & ahead);
|
||||
ahead /= mag(ahead);
|
||||
|
||||
vector right = normal ^ ahead;
|
||||
right /= mag(right);
|
||||
|
||||
// Pout<< "normal: " << normal
|
||||
// << " ahead: " << ahead
|
||||
// << " right: " << right
|
||||
// << endl;
|
||||
|
||||
scalar atanTurn = -GREAT;
|
||||
label bestAtanPoint = -1;
|
||||
|
||||
forAll(nextPoints, nextI)
|
||||
{
|
||||
// Exclude the point we are coming from; there will always
|
||||
// be more than one edge, so this is safe
|
||||
if (nextPoints[nextI] != prevPointLabel)
|
||||
{
|
||||
// Pout<< "cur point: " << curPoint
|
||||
// << " trying for point: "
|
||||
// << mp[nextPoints[nextI]]
|
||||
// << " " << lp[nextPoints[nextI]];
|
||||
vector newDir = lp[nextPoints[nextI]] - curPoint;
|
||||
// Pout<< " newDir: " << newDir
|
||||
// << " mag: " << mag(newDir) << flush;
|
||||
newDir -= normal*(normal & newDir);
|
||||
scalar magNewDir = mag(newDir);
|
||||
// Pout<< " corrected: " << newDir
|
||||
// << " mag: " << mag(newDir) << flush;
|
||||
|
||||
if (magNewDir < SMALL)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void enrichedPatch::"
|
||||
"calcCutFaces() const"
|
||||
) << "Zero length edge detected. Probable "
|
||||
<< "projection error: slave patch probably "
|
||||
<< "does not project onto master. "
|
||||
<< "Please switch on "
|
||||
<< "enriched patch debug for more info"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
newDir /= magNewDir;
|
||||
|
||||
scalar curAtanTurn =
|
||||
atan2(newDir & right, newDir & ahead);
|
||||
|
||||
// Pout<< " atan: " << curAtanTurn << endl;
|
||||
|
||||
if (curAtanTurn > atanTurn)
|
||||
{
|
||||
bestAtanPoint = nextPoints[nextI];
|
||||
atanTurn = curAtanTurn;
|
||||
}
|
||||
} // end of prev point skip
|
||||
} // end of next point selection
|
||||
|
||||
// Pout<< " bestAtanPoint: " << bestAtanPoint << " or "
|
||||
// << mp[bestAtanPoint]
|
||||
// << endl;
|
||||
|
||||
// Selected next best point.
|
||||
|
||||
// Pout<< "cutFaceGlobalPoints: "
|
||||
// << cutFaceGlobalPoints
|
||||
// << endl;
|
||||
|
||||
// Check if the edge about to be added has been used
|
||||
// in the current face or twice in other faces. If
|
||||
// so, the face is bad.
|
||||
const label whichNextPoint = curLocalFace.which(curPointLabel);
|
||||
|
||||
if
|
||||
(
|
||||
whichNextPoint > -1
|
||||
&& curLocalFace.nextLabel(whichNextPoint) == bestAtanPoint
|
||||
&& usedFaceEdges[whichNextPoint]
|
||||
)
|
||||
{
|
||||
// This edge is already used in current face
|
||||
// face cannot be good; start on a new one
|
||||
|
||||
// Pout<< "Double usage in current face, cannot be good"
|
||||
// << endl;
|
||||
|
||||
completedCutFace = true;
|
||||
}
|
||||
|
||||
|
||||
if (edgesUsedTwice.found(edge(curPointLabel, bestAtanPoint)))
|
||||
{
|
||||
// This edge is already used -
|
||||
// face cannot be good; start on a new one
|
||||
completedCutFace = true;
|
||||
|
||||
// Pout<< "Double usage elsewhere, cannot be good" << endl;
|
||||
}
|
||||
|
||||
if (completedCutFace) continue;
|
||||
|
||||
// Insert the next best point into the list
|
||||
if (mp[bestAtanPoint] == cutFaceGlobalPoints[0])
|
||||
{
|
||||
// Face is completed. Save it and move on to the next
|
||||
// available edge
|
||||
completedCutFace = true;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< " local: " << cutFaceLocalPoints
|
||||
<< " one side: " << faceI;
|
||||
}
|
||||
|
||||
// Append the face
|
||||
face cutFaceGlobal;
|
||||
cutFaceGlobal.transfer(cutFaceGlobalPoints);
|
||||
|
||||
cf.append(cutFaceGlobal);
|
||||
|
||||
face cutFaceLocal;
|
||||
cutFaceLocal.transfer(cutFaceLocalPoints);
|
||||
|
||||
// Pout<< "\ncutFaceLocal: "
|
||||
// << cutFaceLocal.points(lp)
|
||||
// << endl;
|
||||
|
||||
// Go through all edges of the cut faces.
|
||||
// If the edge corresponds to a starting face edge,
|
||||
// mark the starting face edge as true
|
||||
|
||||
forAll(cutFaceLocal, cutI)
|
||||
{
|
||||
const edge curCutFaceEdge
|
||||
(
|
||||
cutFaceLocal[cutI],
|
||||
cutFaceLocal.nextLabel(cutI)
|
||||
);
|
||||
|
||||
// Increment the usage count using two hash sets
|
||||
HashSet<edge, Hash<edge> >::iterator euoIter =
|
||||
edgesUsedOnce.find(curCutFaceEdge);
|
||||
|
||||
if (euoIter == edgesUsedOnce.end())
|
||||
{
|
||||
// Pout<< "Found edge not used before: "
|
||||
// << curCutFaceEdge
|
||||
// << endl;
|
||||
edgesUsedOnce.insert(curCutFaceEdge);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pout<< "Found edge used once: "
|
||||
// << curCutFaceEdge
|
||||
// << endl;
|
||||
edgesUsedOnce.erase(euoIter);
|
||||
edgesUsedTwice.insert(curCutFaceEdge);
|
||||
}
|
||||
|
||||
const label curCutFaceEdgeWhich = curLocalFace.which
|
||||
(
|
||||
curCutFaceEdge.start()
|
||||
);
|
||||
|
||||
if
|
||||
(
|
||||
curCutFaceEdgeWhich > -1
|
||||
&& curLocalFace.nextLabel(curCutFaceEdgeWhich)
|
||||
== curCutFaceEdge.end()
|
||||
)
|
||||
{
|
||||
// Found edge in original face
|
||||
|
||||
// Pout<< "Found edge in orig face: "
|
||||
// << curCutFaceEdge << ": "
|
||||
// << curCutFaceEdgeWhich
|
||||
// << endl;
|
||||
|
||||
usedFaceEdges[curCutFaceEdgeWhich] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Edge not in original face. Add it to seeds
|
||||
|
||||
// Pout<< "Found new edge seed: "
|
||||
// << curCutFaceEdge
|
||||
// << endl;
|
||||
|
||||
edgeSeeds.append(curCutFaceEdge.reverseEdge());
|
||||
}
|
||||
}
|
||||
|
||||
// Find out what the other side is
|
||||
|
||||
// Algorithm
|
||||
|
||||
// If the face is in the slave half of the
|
||||
// enrichedFaces lists, it may be matched against
|
||||
// the master face. It can be recognised by the
|
||||
// fact that all its points belong to one master
|
||||
// face. For this purpose:
|
||||
// 1) Grab the master faces around the point zero
|
||||
// of the cut face and collect all master faces
|
||||
// around it.
|
||||
// 2) Loop through the rest of cut face points and
|
||||
// if the point refers to one of the faces marked
|
||||
// by point zero, increment its count.
|
||||
// 3) When completed, the face whose count is
|
||||
// equal to the number of points in the cut face
|
||||
// is the other side. If this is not the case, there is no
|
||||
// face on the other side.
|
||||
|
||||
if (faceI < slavePatch_.size())
|
||||
{
|
||||
Map<labelList>::const_iterator mpfAddrIter =
|
||||
masterPointFaceAddr.find(cutFaceGlobal[0]);
|
||||
|
||||
bool otherSideFound = false;
|
||||
|
||||
if (mpfAddrIter != masterPointFaceAddr.end())
|
||||
{
|
||||
bool miss = false;
|
||||
|
||||
// Create the label count using point zero
|
||||
const labelList& masterFacesOfPZero = mpfAddrIter();
|
||||
|
||||
labelList hits(masterFacesOfPZero.size(), 1);
|
||||
|
||||
for
|
||||
(
|
||||
label pointI = 1;
|
||||
pointI < cutFaceGlobal.size();
|
||||
pointI++
|
||||
)
|
||||
{
|
||||
Map<labelList>::const_iterator
|
||||
mpfAddrPointIter =
|
||||
masterPointFaceAddr.find
|
||||
(
|
||||
cutFaceGlobal[pointI]
|
||||
);
|
||||
|
||||
if
|
||||
(
|
||||
mpfAddrPointIter
|
||||
== masterPointFaceAddr.end()
|
||||
)
|
||||
{
|
||||
// Point is off the master patch. Skip
|
||||
miss = true;
|
||||
break;
|
||||
}
|
||||
|
||||
const labelList& curMasterFaces =
|
||||
mpfAddrPointIter();
|
||||
|
||||
// For every current face, try to find it in the
|
||||
// zero-list
|
||||
forAll(curMasterFaces, i)
|
||||
{
|
||||
forAll(masterFacesOfPZero, j)
|
||||
{
|
||||
if
|
||||
(
|
||||
curMasterFaces[i]
|
||||
== masterFacesOfPZero[j]
|
||||
)
|
||||
{
|
||||
hits[j]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If all point are found attempt matching
|
||||
if (!miss)
|
||||
{
|
||||
forAll(hits, pointI)
|
||||
{
|
||||
if (hits[pointI] == cutFaceGlobal.size())
|
||||
{
|
||||
// Found other side.
|
||||
otherSideFound = true;
|
||||
|
||||
cfMaster.append
|
||||
(
|
||||
masterFacesOfPZero[pointI]
|
||||
);
|
||||
|
||||
cfSlave.append(faceI);
|
||||
|
||||
// Reverse the face such that it
|
||||
// points out of the master patch
|
||||
cf.last().flip();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< " other side: "
|
||||
<< masterFacesOfPZero[pointI]
|
||||
<< endl;
|
||||
}
|
||||
} // end of hits
|
||||
} // end of for all hits
|
||||
|
||||
} // end of not miss
|
||||
|
||||
if (!otherSideFound || miss)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< " solo slave A" << endl;
|
||||
}
|
||||
|
||||
cfMaster.append(-1);
|
||||
cfSlave.append(faceI);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// First point not in master patch
|
||||
if (debug)
|
||||
{
|
||||
Pout<< " solo slave B" << endl;
|
||||
}
|
||||
|
||||
cfMaster.append(-1);
|
||||
cfSlave.append(faceI);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< " master side" << endl;
|
||||
}
|
||||
|
||||
cfMaster.append(faceI - slavePatch_.size());
|
||||
cfSlave.append(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Face not completed. Prepare for the next point search
|
||||
prevPointLabel = curPointLabel;
|
||||
curPointLabel = bestAtanPoint;
|
||||
curPoint = lp[curPointLabel];
|
||||
cutFaceGlobalPoints.append(mp[curPointLabel]);
|
||||
cutFaceLocalPoints.append(curPointLabel);
|
||||
|
||||
if (debug || cutFaceGlobalPoints.size() > faceSizeDebug)
|
||||
{
|
||||
faceSizeDebug *= 2;
|
||||
|
||||
// Check for duplicate points in the face
|
||||
forAll(cutFaceGlobalPoints, checkI)
|
||||
{
|
||||
for
|
||||
(
|
||||
label checkJ = checkI + 1;
|
||||
checkJ < cutFaceGlobalPoints.size();
|
||||
checkJ++
|
||||
)
|
||||
{
|
||||
if
|
||||
(
|
||||
cutFaceGlobalPoints[checkI]
|
||||
== cutFaceGlobalPoints[checkJ]
|
||||
)
|
||||
{
|
||||
// Shrink local points for debugging
|
||||
cutFaceLocalPoints.shrink();
|
||||
|
||||
face origFace;
|
||||
face origFaceLocal;
|
||||
if (faceI < slavePatch_.size())
|
||||
{
|
||||
origFace = slavePatch_[faceI];
|
||||
origFaceLocal =
|
||||
slavePatch_.localFaces()[faceI];
|
||||
}
|
||||
else
|
||||
{
|
||||
origFace =
|
||||
masterPatch_
|
||||
[faceI - slavePatch_.size()];
|
||||
|
||||
origFaceLocal =
|
||||
masterPatch_.localFaces()
|
||||
[faceI - slavePatch_.size()];
|
||||
}
|
||||
|
||||
FatalErrorIn
|
||||
(
|
||||
"void enrichedPatch::"
|
||||
"calcCutFaces() const"
|
||||
) << "Duplicate point found in cut face. "
|
||||
<< "Error in the face cutting "
|
||||
<< "algorithm for global face "
|
||||
<< origFace << " local face "
|
||||
<< origFaceLocal << nl
|
||||
<< "Slave size: " << slavePatch_.size()
|
||||
<< " Master size: "
|
||||
<< masterPatch_.size()
|
||||
<< " index: " << faceI << ".\n"
|
||||
<< "Face: " << curGlobalFace << nl
|
||||
<< "Cut face: " << cutFaceGlobalPoints
|
||||
<< " local: " << cutFaceLocalPoints
|
||||
<< nl << "Points: "
|
||||
<< face(cutFaceLocalPoints).points(lp)
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end of debug
|
||||
}
|
||||
} while (!completedCutFace);
|
||||
} // end of used edges
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< " Finished face " << faceI << endl;
|
||||
}
|
||||
|
||||
} // end of local faces
|
||||
|
||||
// Re-pack the list into compact storage
|
||||
cutFacesPtr_ = new faceList();
|
||||
cutFacesPtr_->transfer(cf);
|
||||
|
||||
cutFaceMasterPtr_ = new labelList();
|
||||
cutFaceMasterPtr_->transfer(cfMaster);
|
||||
|
||||
cutFaceSlavePtr_ = new labelList();
|
||||
cutFaceSlavePtr_->transfer(cfSlave);
|
||||
}
|
||||
|
||||
|
||||
void Foam::enrichedPatch::clearCutFaces()
|
||||
{
|
||||
deleteDemandDrivenData(cutFacesPtr_);
|
||||
deleteDemandDrivenData(cutFaceMasterPtr_);
|
||||
deleteDemandDrivenData(cutFaceSlavePtr_);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::faceList& Foam::enrichedPatch::cutFaces() const
|
||||
{
|
||||
if (!cutFacesPtr_)
|
||||
{
|
||||
calcCutFaces();
|
||||
}
|
||||
|
||||
return *cutFacesPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::labelList& Foam::enrichedPatch::cutFaceMaster() const
|
||||
{
|
||||
if (!cutFaceMasterPtr_)
|
||||
{
|
||||
calcCutFaces();
|
||||
}
|
||||
|
||||
return *cutFaceMasterPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::labelList& Foam::enrichedPatch::cutFaceSlave() const
|
||||
{
|
||||
if (!cutFaceSlavePtr_)
|
||||
{
|
||||
calcCutFaces();
|
||||
}
|
||||
|
||||
return *cutFaceSlavePtr_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,443 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "enrichedPatch.H"
|
||||
#include "DynamicList.H"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::label Foam::enrichedPatch::enrichedFaceRatio_ = 3;
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::enrichedPatch::calcEnrichedFaces
|
||||
(
|
||||
const labelListList& pointsIntoMasterEdges,
|
||||
const labelListList& pointsIntoSlaveEdges,
|
||||
const pointField& projectedSlavePoints
|
||||
)
|
||||
{
|
||||
if (enrichedFacesPtr_)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void enrichedPatch::calcEnrichedFaces\n"
|
||||
"(\n"
|
||||
" const labelListList& pointsIntoMasterEdges,\n"
|
||||
" const labelListList& pointsIntoSlaveEdges,\n"
|
||||
" const pointField& projectedSlavePoints\n"
|
||||
")"
|
||||
) << "Enriched faces already calculated."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Create a list of enriched faces
|
||||
// Algorithm:
|
||||
// 1) Grab the original face and start from point zero.
|
||||
// 2) If the point has been merged away, grab the merge label;
|
||||
// otherwise, keep the original label.
|
||||
// 3) Go to the next edge. Collect all the points to be added along
|
||||
// the edge; order them in the necessary direction and insert onto the
|
||||
// face.
|
||||
// 4) Grab the next point and return on step 2.
|
||||
enrichedFacesPtr_ = new faceList(masterPatch_.size() + slavePatch_.size());
|
||||
faceList& enrichedFaces = *enrichedFacesPtr_;
|
||||
|
||||
label nEnrichedFaces = 0;
|
||||
|
||||
const pointField& masterLocalPoints = masterPatch_.localPoints();
|
||||
const faceList& masterLocalFaces = masterPatch_.localFaces();
|
||||
const labelListList& masterFaceEdges = masterPatch_.faceEdges();
|
||||
|
||||
const faceList& slaveLocalFaces = slavePatch_.localFaces();
|
||||
const labelListList& slaveFaceEdges = slavePatch_.faceEdges();
|
||||
|
||||
// For correct functioning of the enrichedPatch class, the slave
|
||||
// faces need to be inserted first. See comments in
|
||||
// enrichedPatch.H
|
||||
|
||||
// Get reference to the point merge map
|
||||
const Map<label>& pmm = pointMergeMap();
|
||||
|
||||
// Add slave faces into the enriched faces list
|
||||
|
||||
forAll(slavePatch_, faceI)
|
||||
{
|
||||
const face oldFace = slavePatch_[faceI];
|
||||
const face oldLocalFace = slaveLocalFaces[faceI];
|
||||
// Info<< "old slave face " << faceI << ": " << oldFace << endl;
|
||||
const labelList& curEdges = slaveFaceEdges[faceI];
|
||||
|
||||
DynamicList<label> newFace(oldFace.size()*enrichedFaceRatio_);
|
||||
|
||||
// Note: The number of points and edges in a face is always identical
|
||||
// so both can be done is the same loop
|
||||
forAll(oldFace, i)
|
||||
{
|
||||
// Add the point
|
||||
Map<label>::const_iterator mpIter =
|
||||
pmm.find(oldFace[i]);
|
||||
|
||||
if (mpIter == pmm.end())
|
||||
{
|
||||
// Point not mapped
|
||||
newFace.append(oldFace[i]);
|
||||
|
||||
// Add the projected point into the patch support
|
||||
pointMap().insert
|
||||
(
|
||||
oldFace[i], // Global label of point
|
||||
projectedSlavePoints[oldLocalFace[i]] // Projected position
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Point mapped
|
||||
newFace.append(mpIter());
|
||||
|
||||
// Add the projected point into the patch support
|
||||
pointMap().insert
|
||||
(
|
||||
mpIter(), // Merged global label of point
|
||||
projectedSlavePoints[oldLocalFace[i]] // Projected position
|
||||
);
|
||||
}
|
||||
|
||||
// Grab the edge points
|
||||
|
||||
const labelList& slavePointsOnEdge =
|
||||
pointsIntoSlaveEdges[curEdges[i]];
|
||||
|
||||
// Info<< "slavePointsOnEdge for "
|
||||
// << curEdges[i] << ": " << slavePointsOnEdge
|
||||
// << endl;
|
||||
|
||||
// If there are no points on the edge, skip everything
|
||||
// If there is only one point, no need for sorting
|
||||
if (slavePointsOnEdge.size())
|
||||
{
|
||||
// Sort edge points in order
|
||||
scalarField edgePointWeights(slavePointsOnEdge.size());
|
||||
const point& startPoint = projectedSlavePoints[oldLocalFace[i]];
|
||||
|
||||
vector e =
|
||||
projectedSlavePoints[oldLocalFace.nextLabel(i)]
|
||||
- startPoint;
|
||||
|
||||
scalar magSqrE = magSqr(e);
|
||||
|
||||
if (magSqrE > SMALL)
|
||||
{
|
||||
e /= magSqrE;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void enrichedPatch::calcEnrichedFaces\n"
|
||||
"(\n"
|
||||
" const labelListList& pointsIntoMasterEdges,\n"
|
||||
" const labelListList& pointsIntoSlaveEdges,\n"
|
||||
" const pointField& projectedSlavePoints\n"
|
||||
")"
|
||||
) << "Zero length edge in slave patch for face " << i
|
||||
<< ". This is not allowed."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
pointField slavePosOnEdge(slavePointsOnEdge.size());
|
||||
|
||||
forAll(slavePointsOnEdge, edgePointI)
|
||||
{
|
||||
slavePosOnEdge[edgePointI] =
|
||||
pointMap().find(slavePointsOnEdge[edgePointI])();
|
||||
|
||||
edgePointWeights[edgePointI] =
|
||||
(e & (slavePosOnEdge[edgePointI] - startPoint));
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
// Check weights: all new points should be on the edge
|
||||
if (min(edgePointWeights) < 0 || max(edgePointWeights) > 1)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void enrichedPatch::calcEnrichedFaces\n"
|
||||
"(\n"
|
||||
" const labelListList& pointsIntoMasterEdges,\n"
|
||||
" const labelListList& pointsIntoSlaveEdges,\n"
|
||||
" const pointField& projectedSlavePoints\n"
|
||||
")"
|
||||
) << "Invalid point edge weights. Some of points are"
|
||||
<< " not on the edge for edge " << curEdges[i]
|
||||
<< " of face " << faceI << " in slave patch." << nl
|
||||
<< "Min weight: " << min(edgePointWeights)
|
||||
<< " Max weight: " << max(edgePointWeights)
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
// Go through the points and collect them based on
|
||||
// weights from lower to higher. This gives the
|
||||
// correct order of points along the edge.
|
||||
forAll(edgePointWeights, passI)
|
||||
{
|
||||
// Max weight can only be one, so the sorting is
|
||||
// done by elimination.
|
||||
label nextPoint = -1;
|
||||
scalar dist = 2;
|
||||
|
||||
forAll(edgePointWeights, wI)
|
||||
{
|
||||
if (edgePointWeights[wI] < dist)
|
||||
{
|
||||
dist = edgePointWeights[wI];
|
||||
nextPoint = wI;
|
||||
}
|
||||
}
|
||||
|
||||
// Insert the next point and reset its weight to exclude it
|
||||
// from future picks
|
||||
newFace.append(slavePointsOnEdge[nextPoint]);
|
||||
edgePointWeights[nextPoint] = GREAT;
|
||||
|
||||
// Add the point into patch support
|
||||
pointMap().insert
|
||||
(
|
||||
slavePointsOnEdge[nextPoint],
|
||||
slavePosOnEdge[nextPoint]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Info<< "New slave face " << faceI << ": " << newFace << endl;
|
||||
|
||||
// Add the new face to the list
|
||||
enrichedFaces[nEnrichedFaces].transfer(newFace);
|
||||
nEnrichedFaces++;
|
||||
}
|
||||
|
||||
// Add master faces into the enriched faces list
|
||||
|
||||
forAll(masterPatch_, faceI)
|
||||
{
|
||||
const face& oldFace = masterPatch_[faceI];
|
||||
const face& oldLocalFace = masterLocalFaces[faceI];
|
||||
// Info<< "old master face: " << oldFace << endl;
|
||||
const labelList& curEdges = masterFaceEdges[faceI];
|
||||
|
||||
DynamicList<label> newFace(oldFace.size()*enrichedFaceRatio_);
|
||||
|
||||
// Note: The number of points and edges in a face is always identical
|
||||
// so both can be done is the same loop
|
||||
forAll(oldFace, i)
|
||||
{
|
||||
// Add the point
|
||||
Map<label>::const_iterator mpIter =
|
||||
pmm.find(oldFace[i]);
|
||||
|
||||
if (mpIter == pmm.end())
|
||||
{
|
||||
// Point not mapped
|
||||
newFace.append(oldFace[i]);
|
||||
|
||||
// Add the point into patch support
|
||||
pointMap().insert
|
||||
(
|
||||
oldFace[i],
|
||||
masterLocalPoints[oldLocalFace[i]]
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Point mapped
|
||||
newFace.append(mpIter());
|
||||
|
||||
// Add the point into support
|
||||
pointMap().insert(mpIter(), masterLocalPoints[oldLocalFace[i]]);
|
||||
}
|
||||
|
||||
// Grab the edge points
|
||||
|
||||
const labelList& masterPointsOnEdge =
|
||||
pointsIntoMasterEdges[curEdges[i]];
|
||||
|
||||
// If there are no points on the edge, skip everything
|
||||
// If there is only one point, no need for sorting
|
||||
if (masterPointsOnEdge.size())
|
||||
{
|
||||
// Sort edge points in order
|
||||
scalarField edgePointWeights(masterPointsOnEdge.size());
|
||||
const point& startPoint = masterLocalPoints[oldLocalFace[i]];
|
||||
|
||||
vector e =
|
||||
masterLocalPoints[oldLocalFace.nextLabel(i)]
|
||||
- startPoint;
|
||||
|
||||
scalar magSqrE = magSqr(e);
|
||||
|
||||
if (magSqrE > SMALL)
|
||||
{
|
||||
e /= magSqrE;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void enrichedPatch::calcEnrichedFaces\n"
|
||||
"(\n"
|
||||
" const labelListList& pointsIntoMasterEdges,\n"
|
||||
" const labelListList& pointsIntoSlaveEdges,\n"
|
||||
" const pointField& projectedSlavePoints\n"
|
||||
")"
|
||||
) << "Zero length edge in master patch for face " << i
|
||||
<< ". This is not allowed."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
pointField masterPosOnEdge(masterPointsOnEdge.size());
|
||||
|
||||
forAll(masterPointsOnEdge, edgePointI)
|
||||
{
|
||||
masterPosOnEdge[edgePointI] =
|
||||
pointMap().find(masterPointsOnEdge[edgePointI])();
|
||||
|
||||
edgePointWeights[edgePointI] =
|
||||
(e & (masterPosOnEdge[edgePointI] - startPoint));
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
// Check weights: all new points should be on the edge
|
||||
if (min(edgePointWeights) < 0 || max(edgePointWeights) > 1)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void enrichedPatch::calcEnrichedFaces\n"
|
||||
"(\n"
|
||||
" const labelListList& pointsIntoMasterEdges,\n"
|
||||
" const labelListList& pointsIntoSlaveEdges,\n"
|
||||
" const pointField& projectedSlavePoints\n"
|
||||
")"
|
||||
) << "Invalid point edge weights. Some of points are"
|
||||
<< " not on the edge for edge " << curEdges[i]
|
||||
<< " of face " << faceI << " in master patch." << nl
|
||||
<< "Min weight: " << min(edgePointWeights)
|
||||
<< " Max weight: " << max(edgePointWeights)
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
// Go through the points and collect them based on
|
||||
// weights from lower to higher. This gives the
|
||||
// correct order of points along the edge.
|
||||
forAll(edgePointWeights, passI)
|
||||
{
|
||||
// Max weight can only be one, so the sorting is
|
||||
// done by elimination.
|
||||
label nextPoint = -1;
|
||||
scalar dist = 2;
|
||||
|
||||
forAll(edgePointWeights, wI)
|
||||
{
|
||||
if (edgePointWeights[wI] < dist)
|
||||
{
|
||||
dist = edgePointWeights[wI];
|
||||
nextPoint = wI;
|
||||
}
|
||||
}
|
||||
|
||||
// Insert the next point and reset its weight to exclude it
|
||||
// from future picks
|
||||
newFace.append(masterPointsOnEdge[nextPoint]);
|
||||
edgePointWeights[nextPoint] = GREAT;
|
||||
|
||||
// Add the point into patch support
|
||||
pointMap().insert
|
||||
(
|
||||
masterPointsOnEdge[nextPoint],
|
||||
masterPosOnEdge[nextPoint]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Info<< "New master face: " << newFace << endl;
|
||||
|
||||
// Add the new face to the list
|
||||
enrichedFaces[nEnrichedFaces].transfer(newFace);
|
||||
nEnrichedFaces++;
|
||||
}
|
||||
|
||||
// Check the support for the enriched patch
|
||||
if (debug)
|
||||
{
|
||||
if (!checkSupport())
|
||||
{
|
||||
Info<< "Enriched patch support OK. Slave faces: "
|
||||
<< slavePatch_.size() << " Master faces: "
|
||||
<< masterPatch_.size() << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void enrichedPatch::calcEnrichedFaces\n"
|
||||
"(\n"
|
||||
" const labelListList& pointsIntoMasterEdges,\n"
|
||||
" const labelListList& pointsIntoSlaveEdges,\n"
|
||||
" const pointField& projectedSlavePoints\n"
|
||||
")"
|
||||
) << "Error in enriched patch support"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::faceList& Foam::enrichedPatch::enrichedFaces() const
|
||||
{
|
||||
if (!enrichedFacesPtr_)
|
||||
{
|
||||
FatalErrorIn("const faceList& enrichedPatch::enrichedFaces() const")
|
||||
<< "Enriched faces not available yet. Please use "
|
||||
<< "void enrichedPatch::calcEnrichedFaces\n"
|
||||
<< "(\n"
|
||||
<< " const labelListList& pointsIntoMasterEdges,\n"
|
||||
<< " const labelListList& pointsIntoSlaveEdges,\n"
|
||||
<< " const pointField& projectedSlavePoints\n"
|
||||
<< ")"
|
||||
<< " before trying to access faces."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return *enrichedFacesPtr_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,159 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "enrichedPatch.H"
|
||||
#include "primitiveMesh.H"
|
||||
#include "demandDrivenData.H"
|
||||
#include "DynamicList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::label Foam::enrichedPatch::nFaceHits_ = 4;
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::enrichedPatch::calcMasterPointFaces() const
|
||||
{
|
||||
if (masterPointFacesPtr_)
|
||||
{
|
||||
FatalErrorIn("void enrichedPatch::calcMasterPointFaces() const")
|
||||
<< "Master point face addressing already calculated."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Note:
|
||||
// Master point face addressing lists the master faces for all points
|
||||
// in the enriched patch support (if there are no master faces, which is
|
||||
// normal, the list will be empty). The index represents the index of
|
||||
// the master face rather than the index from the enriched patch
|
||||
// Master face points lists the points of the enriched master face plus
|
||||
// points projected into the master face
|
||||
|
||||
Map<DynamicList<label> > mpf(meshPoints().size());
|
||||
|
||||
const faceList& ef = enrichedFaces();
|
||||
|
||||
// Add the original face points
|
||||
forAll(masterPatch_, faceI)
|
||||
{
|
||||
const face& curFace = ef[faceI + slavePatch_.size()];
|
||||
// Pout<< "Cur face in pfAddr: " << curFace << endl;
|
||||
forAll(curFace, pointI)
|
||||
{
|
||||
Map<DynamicList<label> >::iterator mpfIter =
|
||||
mpf.find(curFace[pointI]);
|
||||
|
||||
if (mpfIter == mpf.end())
|
||||
{
|
||||
// Not found, add new dynamic list
|
||||
mpf.insert
|
||||
(
|
||||
curFace[pointI],
|
||||
DynamicList<label>(primitiveMesh::facesPerPoint_)
|
||||
);
|
||||
|
||||
// Iterator is invalidated - have to find again
|
||||
mpf.find(curFace[pointI])().append(faceI);
|
||||
}
|
||||
else
|
||||
{
|
||||
mpfIter().append(faceI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the projected points which hit the face
|
||||
const labelList& slaveMeshPoints = slavePatch_.meshPoints();
|
||||
|
||||
forAll(slavePointFaceHits_, pointI)
|
||||
{
|
||||
if
|
||||
(
|
||||
slavePointPointHits_[pointI] < 0
|
||||
&& slavePointEdgeHits_[pointI] < 0
|
||||
&& slavePointFaceHits_[pointI].hit()
|
||||
)
|
||||
{
|
||||
// Get the index of projected point corresponding to this slave
|
||||
// point
|
||||
const label mergedSmp =
|
||||
pointMergeMap().find(slaveMeshPoints[pointI])();
|
||||
|
||||
Map<DynamicList<label> >::iterator mpfIter =
|
||||
mpf.find(mergedSmp);
|
||||
|
||||
if (mpfIter == mpf.end())
|
||||
{
|
||||
// Not found, add new dynamic list
|
||||
mpf.insert
|
||||
(
|
||||
mergedSmp,
|
||||
DynamicList<label>(primitiveMesh::facesPerPoint_)
|
||||
);
|
||||
|
||||
// Iterator is invalidated - have to find again
|
||||
mpf.find(mergedSmp)().append
|
||||
(
|
||||
slavePointFaceHits_[pointI].hitObject()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
mpfIter().append(slavePointFaceHits_[pointI].hitObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Re-pack dynamic lists into normal lists
|
||||
const labelList mpfToc = mpf.toc();
|
||||
|
||||
masterPointFacesPtr_ = new Map<labelList>(2*mpfToc.size());
|
||||
Map<labelList>& masterPointFaceAddr = *masterPointFacesPtr_;
|
||||
|
||||
forAll(mpfToc, mpfTocI)
|
||||
{
|
||||
labelList l;
|
||||
l.transfer(mpf.find(mpfToc[mpfTocI])());
|
||||
|
||||
masterPointFaceAddr.insert(mpfToc[mpfTocI], l);
|
||||
}
|
||||
// Pout<< "masterPointFaceAddr: " << masterPointFaceAddr << endl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::Map<Foam::labelList>& Foam::enrichedPatch::masterPointFaces() const
|
||||
{
|
||||
if (!masterPointFacesPtr_)
|
||||
{
|
||||
calcMasterPointFaces();
|
||||
}
|
||||
|
||||
return *masterPointFacesPtr_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,105 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "enrichedPatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::enrichedPatch::completePointMap() const
|
||||
{
|
||||
if (pointMapComplete_)
|
||||
{
|
||||
FatalErrorIn("void enrichedPatch::completePointMap() const")
|
||||
<< "Point map already completed"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
pointMapComplete_ = true;
|
||||
|
||||
const Map<label>& pmm = pointMergeMap();
|
||||
|
||||
// Get the mesh points for both patches. If the point has not been
|
||||
// merged away, add it to the map
|
||||
|
||||
// Do master patch
|
||||
const labelList& masterMeshPoints = masterPatch_.meshPoints();
|
||||
const pointField& masterLocalPoints = masterPatch_.localPoints();
|
||||
|
||||
forAll(masterMeshPoints, pointI)
|
||||
{
|
||||
if (!pmm.found(masterMeshPoints[pointI]))
|
||||
{
|
||||
pointMap_.insert
|
||||
(
|
||||
masterMeshPoints[pointI],
|
||||
masterLocalPoints[pointI]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Do slave patch
|
||||
const labelList& slaveMeshPoints = slavePatch_.meshPoints();
|
||||
const pointField& slaveLocalPoints = slavePatch_.localPoints();
|
||||
|
||||
forAll(slaveMeshPoints, pointI)
|
||||
{
|
||||
if (!pmm.found(slaveMeshPoints[pointI]))
|
||||
{
|
||||
pointMap_.insert
|
||||
(
|
||||
slaveMeshPoints[pointI],
|
||||
slaveLocalPoints[pointI]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
Foam::Map<Foam::point>& Foam::enrichedPatch::pointMap()
|
||||
{
|
||||
if (!pointMapComplete_)
|
||||
{
|
||||
completePointMap();
|
||||
}
|
||||
|
||||
return pointMap_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::Map<Foam::point>& Foam::enrichedPatch::pointMap() const
|
||||
{
|
||||
if (!pointMapComplete_)
|
||||
{
|
||||
completePointMap();
|
||||
}
|
||||
|
||||
return pointMap_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,115 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "enrichedPatch.H"
|
||||
#include "primitiveMesh.H"
|
||||
#include "DynamicList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::enrichedPatch::calcPointPoints() const
|
||||
{
|
||||
// Calculate point-point addressing
|
||||
if (pointPointsPtr_)
|
||||
{
|
||||
FatalErrorIn("void enrichedPatch::calcPointPoints() const")
|
||||
<< "Point-point addressing already calculated."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Algorithm:
|
||||
// Go through all faces and add the previous and next point as the
|
||||
// neighbour for each point. While inserting points, reject the
|
||||
// duplicates (as every internal edge will be visited twice).
|
||||
List<DynamicList<label, primitiveMesh::edgesPerPoint_> >
|
||||
pp(meshPoints().size());
|
||||
|
||||
const faceList& lf = localFaces();
|
||||
|
||||
register bool found = false;
|
||||
|
||||
forAll(lf, faceI)
|
||||
{
|
||||
const face& curFace = lf[faceI];
|
||||
|
||||
forAll(curFace, pointI)
|
||||
{
|
||||
DynamicList<label, primitiveMesh::edgesPerPoint_>&
|
||||
curPp = pp[curFace[pointI]];
|
||||
|
||||
// Do next label
|
||||
label next = curFace.nextLabel(pointI);
|
||||
|
||||
found = false;
|
||||
|
||||
forAll(curPp, i)
|
||||
{
|
||||
if (curPp[i] == next)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
curPp.append(next);
|
||||
}
|
||||
|
||||
// Do previous label
|
||||
label prev = curFace.prevLabel(pointI);
|
||||
found = false;
|
||||
|
||||
forAll(curPp, i)
|
||||
{
|
||||
if (curPp[i] == prev)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
curPp.append(prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Re-pack the list
|
||||
pointPointsPtr_ = new labelListList(pp.size());
|
||||
labelListList& ppAddr = *pointPointsPtr_;
|
||||
|
||||
forAll(pp, pointI)
|
||||
{
|
||||
ppAddr[pointI].transfer(pp[pointI]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
844
src/dynamicMesh/slidingInterface/slidingInterface.C
Normal file
844
src/dynamicMesh/slidingInterface/slidingInterface.C
Normal file
@ -0,0 +1,844 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "slidingInterface.H"
|
||||
#include "polyTopoChanger.H"
|
||||
#include "polyMesh.H"
|
||||
#include "polyTopoChange.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "plane.H"
|
||||
|
||||
// Index of debug signs:
|
||||
// p - adjusting a projection point
|
||||
// * - adjusting edge intersection
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(slidingInterface, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
polyMeshModifier,
|
||||
slidingInterface,
|
||||
dictionary
|
||||
);
|
||||
|
||||
template<>
|
||||
const char* Foam::NamedEnum
|
||||
<
|
||||
Foam::slidingInterface::typeOfMatch,
|
||||
2
|
||||
>::names[] =
|
||||
{
|
||||
"integral",
|
||||
"partial"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
const Foam::NamedEnum<Foam::slidingInterface::typeOfMatch, 2>
|
||||
Foam::slidingInterface::typeOfMatchNames_;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::slidingInterface::checkDefinition()
|
||||
{
|
||||
const polyMesh& mesh = topoChanger().mesh();
|
||||
|
||||
if
|
||||
(
|
||||
!masterFaceZoneID_.active()
|
||||
|| !slaveFaceZoneID_.active()
|
||||
|| !cutPointZoneID_.active()
|
||||
|| !cutFaceZoneID_.active()
|
||||
|| !masterPatchID_.active()
|
||||
|| !slavePatchID_.active()
|
||||
)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void slidingInterface::checkDefinition()"
|
||||
) << "Not all zones and patches needed in the definition "
|
||||
<< "have been found. Please check your mesh definition."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Check the sizes and set up state
|
||||
if
|
||||
(
|
||||
mesh.faceZones()[masterFaceZoneID_.index()].empty()
|
||||
|| mesh.faceZones()[slaveFaceZoneID_.index()].empty()
|
||||
)
|
||||
{
|
||||
FatalErrorIn("void slidingInterface::checkDefinition()")
|
||||
<< "Master or slave face zone contain no faces. "
|
||||
<< "Please check your mesh definition."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "Sliding interface object " << name() << " :" << nl
|
||||
<< " master face zone: " << masterFaceZoneID_.index() << nl
|
||||
<< " slave face zone: " << slaveFaceZoneID_.index() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::slidingInterface::clearOut() const
|
||||
{
|
||||
clearPointProjection();
|
||||
clearAttachedAddressing();
|
||||
clearAddressing();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// Construct from components
|
||||
Foam::slidingInterface::slidingInterface
|
||||
(
|
||||
const word& name,
|
||||
const label index,
|
||||
const polyTopoChanger& mme,
|
||||
const word& masterFaceZoneName,
|
||||
const word& slaveFaceZoneName,
|
||||
const word& cutPointZoneName,
|
||||
const word& cutFaceZoneName,
|
||||
const word& masterPatchName,
|
||||
const word& slavePatchName,
|
||||
const typeOfMatch tom,
|
||||
const bool coupleDecouple,
|
||||
const intersection::algorithm algo
|
||||
)
|
||||
:
|
||||
polyMeshModifier(name, index, mme, true),
|
||||
masterFaceZoneID_
|
||||
(
|
||||
masterFaceZoneName,
|
||||
mme.mesh().faceZones()
|
||||
),
|
||||
slaveFaceZoneID_
|
||||
(
|
||||
slaveFaceZoneName,
|
||||
mme.mesh().faceZones()
|
||||
),
|
||||
cutPointZoneID_
|
||||
(
|
||||
cutPointZoneName,
|
||||
mme.mesh().pointZones()
|
||||
),
|
||||
cutFaceZoneID_
|
||||
(
|
||||
cutFaceZoneName,
|
||||
mme.mesh().faceZones()
|
||||
),
|
||||
masterPatchID_
|
||||
(
|
||||
masterPatchName,
|
||||
mme.mesh().boundaryMesh()
|
||||
),
|
||||
slavePatchID_
|
||||
(
|
||||
slavePatchName,
|
||||
mme.mesh().boundaryMesh()
|
||||
),
|
||||
matchType_(tom),
|
||||
coupleDecouple_(coupleDecouple),
|
||||
attached_(false),
|
||||
projectionAlgo_(algo),
|
||||
trigger_(false),
|
||||
pointMergeTol_(pointMergeTolDefault_),
|
||||
edgeMergeTol_(edgeMergeTolDefault_),
|
||||
nFacesPerSlaveEdge_(nFacesPerSlaveEdgeDefault_),
|
||||
edgeFaceEscapeLimit_(edgeFaceEscapeLimitDefault_),
|
||||
integralAdjTol_(integralAdjTolDefault_),
|
||||
edgeMasterCatchFraction_(edgeMasterCatchFractionDefault_),
|
||||
edgeCoPlanarTol_(edgeCoPlanarTolDefault_),
|
||||
edgeEndCutoffTol_(edgeEndCutoffTolDefault_),
|
||||
cutFaceMasterPtr_(NULL),
|
||||
cutFaceSlavePtr_(NULL),
|
||||
masterFaceCellsPtr_(NULL),
|
||||
slaveFaceCellsPtr_(NULL),
|
||||
masterStickOutFacesPtr_(NULL),
|
||||
slaveStickOutFacesPtr_(NULL),
|
||||
retiredPointMapPtr_(NULL),
|
||||
cutPointEdgePairMapPtr_(NULL),
|
||||
slavePointPointHitsPtr_(NULL),
|
||||
slavePointEdgeHitsPtr_(NULL),
|
||||
slavePointFaceHitsPtr_(NULL),
|
||||
masterPointEdgeHitsPtr_(NULL),
|
||||
projectedSlavePointsPtr_(NULL)
|
||||
{
|
||||
checkDefinition();
|
||||
|
||||
if (attached_)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"Foam::slidingInterface::slidingInterface\n"
|
||||
"(\n"
|
||||
" const word& name,\n"
|
||||
" const label index,\n"
|
||||
" const polyTopoChanger& mme,\n"
|
||||
" const word& masterFaceZoneName,\n"
|
||||
" const word& slaveFaceZoneName,\n"
|
||||
" const word& cutFaceZoneName,\n"
|
||||
" const word& cutPointZoneName,\n"
|
||||
" const word& masterPatchName,\n"
|
||||
" const word& slavePatchName,\n"
|
||||
" const typeOfMatch tom,\n"
|
||||
" const bool coupleDecouple\n"
|
||||
")"
|
||||
) << "Creation of a sliding interface from components "
|
||||
<< "in attached state not supported."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
else
|
||||
{
|
||||
calcAttachedAddressing();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Construct from components
|
||||
Foam::slidingInterface::slidingInterface
|
||||
(
|
||||
const word& name,
|
||||
const dictionary& dict,
|
||||
const label index,
|
||||
const polyTopoChanger& mme
|
||||
)
|
||||
:
|
||||
polyMeshModifier(name, index, mme, Switch(dict.lookup("active"))),
|
||||
masterFaceZoneID_
|
||||
(
|
||||
dict.lookup("masterFaceZoneName"),
|
||||
mme.mesh().faceZones()
|
||||
),
|
||||
slaveFaceZoneID_
|
||||
(
|
||||
dict.lookup("slaveFaceZoneName"),
|
||||
mme.mesh().faceZones()
|
||||
),
|
||||
cutPointZoneID_
|
||||
(
|
||||
dict.lookup("cutPointZoneName"),
|
||||
mme.mesh().pointZones()
|
||||
),
|
||||
cutFaceZoneID_
|
||||
(
|
||||
dict.lookup("cutFaceZoneName"),
|
||||
mme.mesh().faceZones()
|
||||
),
|
||||
masterPatchID_
|
||||
(
|
||||
dict.lookup("masterPatchName"),
|
||||
mme.mesh().boundaryMesh()
|
||||
),
|
||||
slavePatchID_
|
||||
(
|
||||
dict.lookup("slavePatchName"),
|
||||
mme.mesh().boundaryMesh()
|
||||
),
|
||||
matchType_(typeOfMatchNames_.read((dict.lookup("typeOfMatch")))),
|
||||
coupleDecouple_(dict.lookup("coupleDecouple")),
|
||||
attached_(dict.lookup("attached")),
|
||||
projectionAlgo_
|
||||
(
|
||||
intersection::algorithmNames_.read(dict.lookup("projection"))
|
||||
),
|
||||
trigger_(false),
|
||||
cutFaceMasterPtr_(NULL),
|
||||
cutFaceSlavePtr_(NULL),
|
||||
masterFaceCellsPtr_(NULL),
|
||||
slaveFaceCellsPtr_(NULL),
|
||||
masterStickOutFacesPtr_(NULL),
|
||||
slaveStickOutFacesPtr_(NULL),
|
||||
retiredPointMapPtr_(NULL),
|
||||
cutPointEdgePairMapPtr_(NULL),
|
||||
slavePointPointHitsPtr_(NULL),
|
||||
slavePointEdgeHitsPtr_(NULL),
|
||||
slavePointFaceHitsPtr_(NULL),
|
||||
masterPointEdgeHitsPtr_(NULL),
|
||||
projectedSlavePointsPtr_(NULL)
|
||||
{
|
||||
// Optionally default tolerances from dictionary
|
||||
setTolerances(dict);
|
||||
|
||||
checkDefinition();
|
||||
|
||||
// If the interface is attached, the master and slave face zone addressing
|
||||
// needs to be read in; otherwise it will be created
|
||||
if (attached_)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "slidingInterface::slidingInterface(...) "
|
||||
<< " for object " << name << " : "
|
||||
<< "Interface attached. Reading master and slave face zones "
|
||||
<< "and retired point lookup." << endl;
|
||||
}
|
||||
|
||||
// The face zone addressing is written out in the definition dictionary
|
||||
masterFaceCellsPtr_ = new labelList(dict.lookup("masterFaceCells"));
|
||||
slaveFaceCellsPtr_ = new labelList(dict.lookup("slaveFaceCells"));
|
||||
|
||||
masterStickOutFacesPtr_ =
|
||||
new labelList(dict.lookup("masterStickOutFaces"));
|
||||
slaveStickOutFacesPtr_ =
|
||||
new labelList(dict.lookup("slaveStickOutFaces"));
|
||||
|
||||
retiredPointMapPtr_ = new Map<label>(dict.lookup("retiredPointMap"));
|
||||
cutPointEdgePairMapPtr_ =
|
||||
new Map<Pair<edge> >(dict.lookup("cutPointEdgePairMap"));
|
||||
}
|
||||
else
|
||||
{
|
||||
calcAttachedAddressing();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::slidingInterface::~slidingInterface()
|
||||
{
|
||||
clearOut();
|
||||
}
|
||||
|
||||
|
||||
void Foam::slidingInterface::clearAddressing() const
|
||||
{
|
||||
deleteDemandDrivenData(cutFaceMasterPtr_);
|
||||
deleteDemandDrivenData(cutFaceSlavePtr_);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::faceZoneID& Foam::slidingInterface::masterFaceZoneID() const
|
||||
{
|
||||
return masterFaceZoneID_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::faceZoneID& Foam::slidingInterface::slaveFaceZoneID() const
|
||||
{
|
||||
return slaveFaceZoneID_;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::slidingInterface::changeTopology() const
|
||||
{
|
||||
if (coupleDecouple_)
|
||||
{
|
||||
// Always changes. If not attached, project points
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "bool slidingInterface::changeTopology() const "
|
||||
<< "for object " << name() << " : "
|
||||
<< "Couple-decouple mode." << endl;
|
||||
}
|
||||
|
||||
if (!attached_)
|
||||
{
|
||||
projectPoints();
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
attached_
|
||||
&& !topoChanger().mesh().changing()
|
||||
)
|
||||
{
|
||||
// If the mesh is not moving or morphing and the interface is
|
||||
// already attached, the topology will not change
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if the motion changes point projection
|
||||
return projectPoints();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::slidingInterface::setRefinement(polyTopoChange& ref) const
|
||||
{
|
||||
if (coupleDecouple_)
|
||||
{
|
||||
if (attached_)
|
||||
{
|
||||
// Attached, coupling
|
||||
decoupleInterface(ref);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Detached, coupling
|
||||
coupleInterface(ref);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (trigger_)
|
||||
{
|
||||
if (attached_)
|
||||
{
|
||||
// Clear old coupling data
|
||||
clearCouple(ref);
|
||||
}
|
||||
|
||||
coupleInterface(ref);
|
||||
|
||||
trigger_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::slidingInterface::modifyMotionPoints(pointField& motionPoints) const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "void slidingInterface::modifyMotionPoints("
|
||||
<< "pointField& motionPoints) const for object " << name() << " : "
|
||||
<< "Adjusting motion points." << endl;
|
||||
}
|
||||
|
||||
const polyMesh& mesh = topoChanger().mesh();
|
||||
|
||||
// Get point from the cut zone
|
||||
const labelList& cutPoints = mesh.pointZones()[cutPointZoneID_.index()];
|
||||
|
||||
if (cutPoints.size() && !projectedSlavePointsPtr_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
const pointField& projectedSlavePoints = *projectedSlavePointsPtr_;
|
||||
|
||||
const Map<label>& rpm = retiredPointMap();
|
||||
|
||||
const Map<Pair<edge> >& cpepm = cutPointEdgePairMap();
|
||||
|
||||
const Map<label>& slaveZonePointMap =
|
||||
mesh.faceZones()[slaveFaceZoneID_.index()]().meshPointMap();
|
||||
|
||||
const primitiveFacePatch& masterPatch =
|
||||
mesh.faceZones()[masterFaceZoneID_.index()]();
|
||||
const edgeList& masterEdges = masterPatch.edges();
|
||||
const pointField& masterLocalPoints = masterPatch.localPoints();
|
||||
|
||||
const primitiveFacePatch& slavePatch =
|
||||
mesh.faceZones()[slaveFaceZoneID_.index()]();
|
||||
const edgeList& slaveEdges = slavePatch.edges();
|
||||
const pointField& slaveLocalPoints = slavePatch.localPoints();
|
||||
const vectorField& slavePointNormals = slavePatch.pointNormals();
|
||||
|
||||
forAll(cutPoints, pointI)
|
||||
{
|
||||
// Try to find the cut point in retired points
|
||||
Map<label>::const_iterator rpmIter = rpm.find(cutPoints[pointI]);
|
||||
|
||||
if (rpmIter != rpm.end())
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "p";
|
||||
}
|
||||
|
||||
// Cut point is a retired point
|
||||
motionPoints[cutPoints[pointI]] =
|
||||
projectedSlavePoints[slaveZonePointMap.find(rpmIter())()];
|
||||
}
|
||||
else
|
||||
{
|
||||
// A cut point is not a projected slave point. Therefore, it
|
||||
// must be an edge-to-edge intersection.
|
||||
|
||||
Map<Pair<edge> >::const_iterator cpepmIter =
|
||||
cpepm.find(cutPoints[pointI]);
|
||||
|
||||
if (cpepmIter != cpepm.end())
|
||||
{
|
||||
// Pout<< "Need to re-create hit for point "
|
||||
// << cutPoints[pointI]
|
||||
// << " lookup: " << cpepmIter()
|
||||
// << endl;
|
||||
|
||||
// Note.
|
||||
// The edge cutting code is repeated in
|
||||
// slidingInterface::coupleInterface. This is done for
|
||||
// efficiency reasons and avoids multiple creation of
|
||||
// cutting planes. Please update both simultaneously.
|
||||
//
|
||||
const edge& globalMasterEdge = cpepmIter().first();
|
||||
|
||||
const label curMasterEdgeIndex =
|
||||
masterPatch.whichEdge
|
||||
(
|
||||
edge
|
||||
(
|
||||
masterPatch.whichPoint
|
||||
(
|
||||
globalMasterEdge.start()
|
||||
),
|
||||
masterPatch.whichPoint
|
||||
(
|
||||
globalMasterEdge.end()
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
const edge& cme = masterEdges[curMasterEdgeIndex];
|
||||
|
||||
// Pout<< "curMasterEdgeIndex: " << curMasterEdgeIndex
|
||||
// << " cme: " << cme
|
||||
// << endl;
|
||||
|
||||
const edge& globalSlaveEdge = cpepmIter().second();
|
||||
|
||||
const label curSlaveEdgeIndex =
|
||||
slavePatch.whichEdge
|
||||
(
|
||||
edge
|
||||
(
|
||||
slavePatch.whichPoint
|
||||
(
|
||||
globalSlaveEdge.start()
|
||||
),
|
||||
slavePatch.whichPoint
|
||||
(
|
||||
globalSlaveEdge.end()
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
const edge& curSlaveEdge = slaveEdges[curSlaveEdgeIndex];
|
||||
// Pout<< "curSlaveEdgeIndex: " << curSlaveEdgeIndex
|
||||
// << " curSlaveEdge: " << curSlaveEdge
|
||||
// << endl;
|
||||
const point& a = projectedSlavePoints[curSlaveEdge.start()];
|
||||
const point& b = projectedSlavePoints[curSlaveEdge.end()];
|
||||
|
||||
point c =
|
||||
0.5*
|
||||
(
|
||||
slaveLocalPoints[curSlaveEdge.start()]
|
||||
+ slavePointNormals[curSlaveEdge.start()]
|
||||
+ slaveLocalPoints[curSlaveEdge.end()]
|
||||
+ slavePointNormals[curSlaveEdge.end()]
|
||||
);
|
||||
|
||||
// Create the plane
|
||||
plane cutPlane(a, b, c);
|
||||
|
||||
linePointRef curSlaveLine =
|
||||
curSlaveEdge.line(slaveLocalPoints);
|
||||
const scalar curSlaveLineMag = curSlaveLine.mag();
|
||||
|
||||
scalar cutOnMaster =
|
||||
cutPlane.lineIntersect
|
||||
(
|
||||
cme.line(masterLocalPoints)
|
||||
);
|
||||
|
||||
if
|
||||
(
|
||||
cutOnMaster > edgeEndCutoffTol_
|
||||
&& cutOnMaster < 1.0 - edgeEndCutoffTol_
|
||||
)
|
||||
{
|
||||
// Master is cut, check the slave
|
||||
point masterCutPoint =
|
||||
masterLocalPoints[cme.start()]
|
||||
+ cutOnMaster*cme.vec(masterLocalPoints);
|
||||
|
||||
pointHit slaveCut =
|
||||
curSlaveLine.nearestDist(masterCutPoint);
|
||||
|
||||
if (slaveCut.hit())
|
||||
{
|
||||
// Strict checking of slave cut to avoid capturing
|
||||
// end points.
|
||||
scalar cutOnSlave =
|
||||
(
|
||||
(
|
||||
slaveCut.hitPoint()
|
||||
- curSlaveLine.start()
|
||||
) & curSlaveLine.vec()
|
||||
)/sqr(curSlaveLineMag);
|
||||
|
||||
// Calculate merge tolerance from the
|
||||
// target edge length
|
||||
scalar mergeTol =
|
||||
edgeCoPlanarTol_*mag(b - a);
|
||||
|
||||
if
|
||||
(
|
||||
cutOnSlave > edgeEndCutoffTol_
|
||||
&& cutOnSlave < 1.0 - edgeEndCutoffTol_
|
||||
&& slaveCut.distance() < mergeTol
|
||||
)
|
||||
{
|
||||
// Cut both master and slave.
|
||||
motionPoints[cutPoints[pointI]] =
|
||||
masterCutPoint;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Pout<< "Missed slave edge!!! This is an error. "
|
||||
<< "Master edge: "
|
||||
<< cme.line(masterLocalPoints)
|
||||
<< " slave edge: " << curSlaveLine
|
||||
<< " point: " << masterCutPoint
|
||||
<< " weight: " <<
|
||||
(
|
||||
(
|
||||
slaveCut.missPoint()
|
||||
- curSlaveLine.start()
|
||||
) & curSlaveLine.vec()
|
||||
)/sqr(curSlaveLineMag)
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Pout<< "Missed master edge!!! This is an error"
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void slidingInterface::modifyMotionPoints"
|
||||
"(pointField&) const"
|
||||
) << "Cut point " << cutPoints[pointI]
|
||||
<< " not recognised as either the projected "
|
||||
<< "or as intersection point. Error in point "
|
||||
<< "projection or data mapping"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (debug)
|
||||
{
|
||||
Pout<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::slidingInterface::updateMesh(const mapPolyMesh& m)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "void slidingInterface::updateMesh(const mapPolyMesh& m)"
|
||||
<< " const for object " << name() << " : "
|
||||
<< "Updating topology." << endl;
|
||||
}
|
||||
|
||||
// Mesh has changed topologically. Update local topological data
|
||||
const polyMesh& mesh = topoChanger().mesh();
|
||||
|
||||
masterFaceZoneID_.update(mesh.faceZones());
|
||||
slaveFaceZoneID_.update(mesh.faceZones());
|
||||
cutPointZoneID_.update(mesh.pointZones());
|
||||
cutFaceZoneID_.update(mesh.faceZones());
|
||||
|
||||
masterPatchID_.update(mesh.boundaryMesh());
|
||||
slavePatchID_.update(mesh.boundaryMesh());
|
||||
|
||||
//MJ:Disabled updating
|
||||
// if (!attached())
|
||||
// {
|
||||
// calcAttachedAddressing();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// renumberAttachedAddressing(m);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
const Foam::pointField& Foam::slidingInterface::pointProjection() const
|
||||
{
|
||||
if (!projectedSlavePointsPtr_)
|
||||
{
|
||||
projectPoints();
|
||||
}
|
||||
|
||||
return *projectedSlavePointsPtr_;
|
||||
}
|
||||
|
||||
void Foam::slidingInterface::setTolerances(const dictionary&dict, bool report)
|
||||
{
|
||||
pointMergeTol_ = dict.lookupOrDefault<scalar>
|
||||
(
|
||||
"pointMergeTol",
|
||||
pointMergeTol_
|
||||
);
|
||||
edgeMergeTol_ = dict.lookupOrDefault<scalar>
|
||||
(
|
||||
"edgeMergeTol",
|
||||
edgeMergeTol_
|
||||
);
|
||||
nFacesPerSlaveEdge_ = dict.lookupOrDefault<label>
|
||||
(
|
||||
"nFacesPerSlaveEdge",
|
||||
nFacesPerSlaveEdge_
|
||||
);
|
||||
edgeFaceEscapeLimit_ = dict.lookupOrDefault<label>
|
||||
(
|
||||
"edgeFaceEscapeLimit",
|
||||
edgeFaceEscapeLimit_
|
||||
);
|
||||
integralAdjTol_ = dict.lookupOrDefault<scalar>
|
||||
(
|
||||
"integralAdjTol",
|
||||
integralAdjTol_
|
||||
);
|
||||
edgeMasterCatchFraction_ = dict.lookupOrDefault<scalar>
|
||||
(
|
||||
"edgeMasterCatchFraction",
|
||||
edgeMasterCatchFraction_
|
||||
);
|
||||
edgeCoPlanarTol_ = dict.lookupOrDefault<scalar>
|
||||
(
|
||||
"edgeCoPlanarTol",
|
||||
edgeCoPlanarTol_
|
||||
);
|
||||
edgeEndCutoffTol_ = dict.lookupOrDefault<scalar>
|
||||
(
|
||||
"edgeEndCutoffTol",
|
||||
edgeEndCutoffTol_
|
||||
);
|
||||
|
||||
if (report)
|
||||
{
|
||||
Info<< "Sliding interface parameters:" << nl
|
||||
<< "pointMergeTol : " << pointMergeTol_ << nl
|
||||
<< "edgeMergeTol : " << edgeMergeTol_ << nl
|
||||
<< "nFacesPerSlaveEdge : " << nFacesPerSlaveEdge_ << nl
|
||||
<< "edgeFaceEscapeLimit : " << edgeFaceEscapeLimit_ << nl
|
||||
<< "integralAdjTol : " << integralAdjTol_ << nl
|
||||
<< "edgeMasterCatchFraction : " << edgeMasterCatchFraction_ << nl
|
||||
<< "edgeCoPlanarTol : " << edgeCoPlanarTol_ << nl
|
||||
<< "edgeEndCutoffTol : " << edgeEndCutoffTol_ << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::slidingInterface::write(Ostream& os) const
|
||||
{
|
||||
os << nl << type() << nl
|
||||
<< name()<< nl
|
||||
<< masterFaceZoneID_.name() << nl
|
||||
<< slaveFaceZoneID_.name() << nl
|
||||
<< cutPointZoneID_.name() << nl
|
||||
<< cutFaceZoneID_.name() << nl
|
||||
<< masterPatchID_.name() << nl
|
||||
<< slavePatchID_.name() << nl
|
||||
<< typeOfMatchNames_[matchType_] << nl
|
||||
<< coupleDecouple_ << nl
|
||||
<< attached_ << endl;
|
||||
}
|
||||
|
||||
|
||||
// To write out all those tolerances
|
||||
#define WRITE_NON_DEFAULT(name) \
|
||||
if ( name ## _ != name ## Default_ )\
|
||||
{ \
|
||||
os << " " #name " " << name ## _ << token::END_STATEMENT << nl; \
|
||||
}
|
||||
|
||||
|
||||
void Foam::slidingInterface::writeDict(Ostream& os) const
|
||||
{
|
||||
os << nl << name() << nl << token::BEGIN_BLOCK << nl
|
||||
<< " type " << type() << token::END_STATEMENT << nl
|
||||
<< " masterFaceZoneName " << masterFaceZoneID_.name()
|
||||
<< token::END_STATEMENT << nl
|
||||
<< " slaveFaceZoneName " << slaveFaceZoneID_.name()
|
||||
<< token::END_STATEMENT << nl
|
||||
<< " cutPointZoneName " << cutPointZoneID_.name()
|
||||
<< token::END_STATEMENT << nl
|
||||
<< " cutFaceZoneName " << cutFaceZoneID_.name()
|
||||
<< token::END_STATEMENT << nl
|
||||
<< " masterPatchName " << masterPatchID_.name()
|
||||
<< token::END_STATEMENT << nl
|
||||
<< " slavePatchName " << slavePatchID_.name()
|
||||
<< token::END_STATEMENT << nl
|
||||
<< " typeOfMatch " << typeOfMatchNames_[matchType_]
|
||||
<< token::END_STATEMENT << nl
|
||||
<< " coupleDecouple " << coupleDecouple_
|
||||
<< token::END_STATEMENT << nl
|
||||
<< " projection " << intersection::algorithmNames_[projectionAlgo_]
|
||||
<< token::END_STATEMENT << nl
|
||||
<< " attached " << attached_
|
||||
<< token::END_STATEMENT << nl
|
||||
<< " active " << active()
|
||||
<< token::END_STATEMENT << nl;
|
||||
|
||||
if (attached_)
|
||||
{
|
||||
masterFaceCellsPtr_->writeEntry("masterFaceCells", os);
|
||||
slaveFaceCellsPtr_->writeEntry("slaveFaceCells", os);
|
||||
masterStickOutFacesPtr_->writeEntry("masterStickOutFaces", os);
|
||||
slaveStickOutFacesPtr_->writeEntry("slaveStickOutFaces", os);
|
||||
|
||||
os << " retiredPointMap " << retiredPointMap()
|
||||
<< token::END_STATEMENT << nl
|
||||
<< " cutPointEdgePairMap " << cutPointEdgePairMap()
|
||||
<< token::END_STATEMENT << nl;
|
||||
}
|
||||
|
||||
WRITE_NON_DEFAULT(pointMergeTol)
|
||||
WRITE_NON_DEFAULT(edgeMergeTol)
|
||||
WRITE_NON_DEFAULT(nFacesPerSlaveEdge)
|
||||
WRITE_NON_DEFAULT(edgeFaceEscapeLimit)
|
||||
WRITE_NON_DEFAULT(integralAdjTol)
|
||||
WRITE_NON_DEFAULT(edgeMasterCatchFraction)
|
||||
WRITE_NON_DEFAULT(edgeCoPlanarTol)
|
||||
WRITE_NON_DEFAULT(edgeEndCutoffTol)
|
||||
|
||||
os << token::END_BLOCK << endl;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
394
src/dynamicMesh/slidingInterface/slidingInterface.H
Normal file
394
src/dynamicMesh/slidingInterface/slidingInterface.H
Normal file
@ -0,0 +1,394 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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::slidingInterface
|
||||
|
||||
Description
|
||||
Sliding interface mesh modifier. Given two face zones, couple the
|
||||
master and slave side using a cutting procedure.
|
||||
|
||||
The coupled faces are collected into the "coupled" zone and can become
|
||||
either internal or placed into a master and slave coupled zone. The
|
||||
remaining faces (uncovered master or slave) are placed into the master
|
||||
and slave patch.
|
||||
|
||||
The definition of the sliding interface can be either integral or partial.
|
||||
Integral interface implies that the slave side completely covers
|
||||
the master (i.e. no faces are uncovered); partial interface
|
||||
implies that the uncovered part of master/slave face zone should
|
||||
become boundary faces.
|
||||
|
||||
SourceFiles
|
||||
slidingInterface.C
|
||||
coupleSlidingInterface.C
|
||||
decoupleSlidingInterface.C
|
||||
slidingInterfaceProjectPoints.C
|
||||
slidingInterfaceAttachedAddressing.C
|
||||
slidingInterfaceClearCouple.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef slidingInterface_H
|
||||
#define slidingInterface_H
|
||||
|
||||
#include "polyMeshModifier.H"
|
||||
#include "primitiveFacePatch.H"
|
||||
#include "polyPatchID.H"
|
||||
#include "ZoneIDs.H"
|
||||
#include "intersection.H"
|
||||
#include "Pair.H"
|
||||
#include "objectHit.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class slidingInterface Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class slidingInterface
|
||||
:
|
||||
public polyMeshModifier
|
||||
{
|
||||
public:
|
||||
|
||||
// Public enumerations
|
||||
|
||||
//- Type of match
|
||||
enum typeOfMatch
|
||||
{
|
||||
INTEGRAL,
|
||||
PARTIAL
|
||||
};
|
||||
|
||||
//- Direction names
|
||||
static const NamedEnum<typeOfMatch, 2> typeOfMatchNames_;
|
||||
|
||||
private:
|
||||
|
||||
// Private data
|
||||
|
||||
//- Master face zone ID
|
||||
faceZoneID masterFaceZoneID_;
|
||||
|
||||
//- Slave face zone ID
|
||||
faceZoneID slaveFaceZoneID_;
|
||||
|
||||
//- Cut point zone ID
|
||||
pointZoneID cutPointZoneID_;
|
||||
|
||||
//- Cut face zone ID
|
||||
faceZoneID cutFaceZoneID_;
|
||||
|
||||
//- Master patch ID
|
||||
polyPatchID masterPatchID_;
|
||||
|
||||
//- Slave patch ID
|
||||
polyPatchID slavePatchID_;
|
||||
|
||||
//- Type of match
|
||||
const typeOfMatch matchType_;
|
||||
|
||||
//- Couple-decouple operation.
|
||||
// If the interface is coupled, decouple it and vice versa.
|
||||
// Used in conjuction with automatic mesh motion
|
||||
mutable Switch coupleDecouple_;
|
||||
|
||||
//- State of the modifier
|
||||
mutable Switch attached_;
|
||||
|
||||
//- Point projection algorithm
|
||||
intersection::algorithm projectionAlgo_;
|
||||
|
||||
//- Trigger topological change
|
||||
mutable bool trigger_;
|
||||
|
||||
// Tolerances. Initialised to static ones below.
|
||||
|
||||
//- Point merge tolerance
|
||||
scalar pointMergeTol_;
|
||||
|
||||
//- Edge merge tolerance
|
||||
scalar edgeMergeTol_;
|
||||
|
||||
//- Estimated number of faces an edge goes through
|
||||
label nFacesPerSlaveEdge_;
|
||||
|
||||
//- Edge-face interaction escape limit
|
||||
label edgeFaceEscapeLimit_;
|
||||
|
||||
//- Integral match point adjustment tolerance
|
||||
scalar integralAdjTol_;
|
||||
|
||||
//- Edge intersection master catch fraction
|
||||
scalar edgeMasterCatchFraction_;
|
||||
|
||||
//- Edge intersection co-planar tolerance
|
||||
scalar edgeCoPlanarTol_;
|
||||
|
||||
//- Edge end cut-off tolerance
|
||||
scalar edgeEndCutoffTol_;
|
||||
|
||||
|
||||
// Private addressing data.
|
||||
|
||||
//- Cut face master face. Gives the index of face in master patch
|
||||
// the cut face has been created from. For a slave-only face
|
||||
// this will be -1
|
||||
mutable labelList* cutFaceMasterPtr_;
|
||||
|
||||
//- Cut face slave face. Gives the index of face in slave patch
|
||||
// the cut face has been created from. For a master-only face
|
||||
// this will be -1
|
||||
mutable labelList* cutFaceSlavePtr_;
|
||||
|
||||
//- Master zone faceCells
|
||||
mutable labelList* masterFaceCellsPtr_;
|
||||
|
||||
//- Slave zone faceCells
|
||||
mutable labelList* slaveFaceCellsPtr_;
|
||||
|
||||
//- Master stick-out faces
|
||||
mutable labelList* masterStickOutFacesPtr_;
|
||||
|
||||
//- Slave stick-out faces
|
||||
mutable labelList* slaveStickOutFacesPtr_;
|
||||
|
||||
//- Retired point mapping.
|
||||
// For every retired slave side point, gives the label of the
|
||||
// master point that replaces it
|
||||
mutable Map<label>* retiredPointMapPtr_;
|
||||
|
||||
//- Cut edge pairs
|
||||
// For cut points created by intersection two edges,
|
||||
// store the master-slave edge pair used in creation
|
||||
mutable Map<Pair<edge> >* cutPointEdgePairMapPtr_;
|
||||
|
||||
//- Slave point hit. The index of master point hit by the
|
||||
// slave point in projection. For no point hit, set to -1
|
||||
mutable labelList* slavePointPointHitsPtr_;
|
||||
|
||||
//- Slave edge hit. The index of master edge hit by the
|
||||
// slave point in projection. For point or no edge hit, set to -1
|
||||
mutable labelList* slavePointEdgeHitsPtr_;
|
||||
|
||||
//- Slave face hit. The index of master face hit by the
|
||||
// slave point in projection.
|
||||
mutable List<objectHit>* slavePointFaceHitsPtr_;
|
||||
|
||||
//- Master point edge hit. The index of slave edge hit by
|
||||
// a master point. For no hit set to -1
|
||||
mutable labelList* masterPointEdgeHitsPtr_;
|
||||
|
||||
//- Projected slave points
|
||||
mutable pointField* projectedSlavePointsPtr_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
slidingInterface(const slidingInterface&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const slidingInterface&);
|
||||
|
||||
//- Clear out
|
||||
void clearOut() const;
|
||||
|
||||
|
||||
//- Check validity of construction data
|
||||
void checkDefinition();
|
||||
|
||||
//- Calculate attached addressing
|
||||
void calcAttachedAddressing() const;
|
||||
|
||||
//- Calculate decoupled zone face-cell addressing
|
||||
void renumberAttachedAddressing(const mapPolyMesh&) const;
|
||||
|
||||
//- Clear attached addressing
|
||||
void clearAttachedAddressing() const;
|
||||
|
||||
|
||||
// Topological changes
|
||||
|
||||
//- Master faceCells
|
||||
const labelList& masterFaceCells() const;
|
||||
|
||||
//- Slave faceCells
|
||||
const labelList& slaveFaceCells() const;
|
||||
|
||||
//- Master stick-out faces
|
||||
const labelList& masterStickOutFaces() const;
|
||||
|
||||
//- Slave stick-out faces
|
||||
const labelList& slaveStickOutFaces() const;
|
||||
|
||||
//- Retired point map
|
||||
const Map<label>& retiredPointMap() const;
|
||||
|
||||
//- Cut point edge pair map
|
||||
const Map<Pair<edge> >& cutPointEdgePairMap() const;
|
||||
|
||||
//- Clear addressing
|
||||
void clearAddressing() const;
|
||||
|
||||
//- Project slave points and compare with the current projection.
|
||||
// If the projection has changed, the sliding interface
|
||||
// changes topologically
|
||||
bool projectPoints() const;
|
||||
|
||||
//- Couple sliding interface
|
||||
void coupleInterface(polyTopoChange& ref) const;
|
||||
|
||||
//- Clear projection
|
||||
void clearPointProjection() const;
|
||||
|
||||
//- Clear old couple
|
||||
void clearCouple(polyTopoChange& ref) const;
|
||||
|
||||
//- Decouple interface (returns it to decoupled state)
|
||||
// Note: this should not be used in normal operation of the
|
||||
// sliding mesh, but only to return the mesh to its
|
||||
// original state
|
||||
void decoupleInterface(polyTopoChange& ref) const;
|
||||
|
||||
|
||||
// Static data members
|
||||
|
||||
//- Point merge tolerance
|
||||
static const scalar pointMergeTolDefault_;
|
||||
|
||||
//- Edge merge tolerance
|
||||
static const scalar edgeMergeTolDefault_;
|
||||
|
||||
//- Estimated number of faces an edge goes through
|
||||
static const label nFacesPerSlaveEdgeDefault_;
|
||||
|
||||
//- Edge-face interaction escape limit
|
||||
static const label edgeFaceEscapeLimitDefault_;
|
||||
|
||||
//- Integral match point adjustment tolerance
|
||||
static const scalar integralAdjTolDefault_;
|
||||
|
||||
//- Edge intersection master catch fraction
|
||||
static const scalar edgeMasterCatchFractionDefault_;
|
||||
|
||||
//- Edge intersection co-planar tolerance
|
||||
static const scalar edgeCoPlanarTolDefault_;
|
||||
|
||||
//- Edge end cut-off tolerance
|
||||
static const scalar edgeEndCutoffTolDefault_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("slidingInterface");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
slidingInterface
|
||||
(
|
||||
const word& name,
|
||||
const label index,
|
||||
const polyTopoChanger& mme,
|
||||
const word& masterFaceZoneName,
|
||||
const word& slaveFaceZoneName,
|
||||
const word& cutPointZoneName,
|
||||
const word& cutFaceZoneName,
|
||||
const word& masterPatchName,
|
||||
const word& slavePatchName,
|
||||
const typeOfMatch tom,
|
||||
const bool coupleDecouple = false,
|
||||
const intersection::algorithm algo = intersection::VISIBLE
|
||||
);
|
||||
|
||||
//- Construct from dictionary
|
||||
slidingInterface
|
||||
(
|
||||
const word& name,
|
||||
const dictionary& dict,
|
||||
const label index,
|
||||
const polyTopoChanger& mme
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~slidingInterface();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return master face zone ID
|
||||
const faceZoneID& masterFaceZoneID() const;
|
||||
|
||||
//- Return slave face zone ID
|
||||
const faceZoneID& slaveFaceZoneID() const;
|
||||
|
||||
//- Return true if attached
|
||||
bool attached() const
|
||||
{
|
||||
return attached_;
|
||||
}
|
||||
|
||||
//- Check for topology change
|
||||
virtual bool changeTopology() const;
|
||||
|
||||
//- Insert the layer addition/removal instructions
|
||||
// into the topological change
|
||||
virtual void setRefinement(polyTopoChange&) const;
|
||||
|
||||
//- Modify motion points to comply with the topological change
|
||||
virtual void modifyMotionPoints(pointField& motionPoints) const;
|
||||
|
||||
//- Force recalculation of locally stored data on topological change
|
||||
virtual void updateMesh(const mapPolyMesh&);
|
||||
|
||||
//- Return projected points for a slave patch
|
||||
const pointField& pointProjection() const;
|
||||
|
||||
//- Set the tolerances from the values in a dictionary
|
||||
void setTolerances(const dictionary&, bool report=false);
|
||||
|
||||
//- Write
|
||||
virtual void write(Ostream&) const;
|
||||
|
||||
//- Write dictionary
|
||||
virtual void writeDict(Ostream&) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,591 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "slidingInterface.H"
|
||||
#include "polyMesh.H"
|
||||
#include "mapPolyMesh.H"
|
||||
#include "polyTopoChanger.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::slidingInterface::calcAttachedAddressing() const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "void Foam::slidingInterface::calcAttachedAddressing() const "
|
||||
<< " for object " << name() << " : "
|
||||
<< "Calculating zone face-cell addressing."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if (!attached_)
|
||||
{
|
||||
// Clear existing addressing
|
||||
clearAttachedAddressing();
|
||||
|
||||
const polyMesh& mesh = topoChanger().mesh();
|
||||
const labelList& own = mesh.faceOwner();
|
||||
const labelList& nei = mesh.faceNeighbour();
|
||||
const faceZoneMesh& faceZones = mesh.faceZones();
|
||||
|
||||
// Master side
|
||||
|
||||
const primitiveFacePatch& masterPatch =
|
||||
faceZones[masterFaceZoneID_.index()]();
|
||||
|
||||
const labelList& masterPatchFaces =
|
||||
faceZones[masterFaceZoneID_.index()];
|
||||
|
||||
const boolList& masterFlip =
|
||||
faceZones[masterFaceZoneID_.index()].flipMap();
|
||||
|
||||
masterFaceCellsPtr_ = new labelList(masterPatchFaces.size());
|
||||
labelList& mfc = *masterFaceCellsPtr_;
|
||||
|
||||
forAll(masterPatchFaces, faceI)
|
||||
{
|
||||
if (masterFlip[faceI])
|
||||
{
|
||||
mfc[faceI] = nei[masterPatchFaces[faceI]];
|
||||
}
|
||||
else
|
||||
{
|
||||
mfc[faceI] = own[masterPatchFaces[faceI]];
|
||||
}
|
||||
}
|
||||
|
||||
// Slave side
|
||||
|
||||
const primitiveFacePatch& slavePatch =
|
||||
faceZones[slaveFaceZoneID_.index()]();
|
||||
|
||||
const labelList& slavePatchFaces =
|
||||
faceZones[slaveFaceZoneID_.index()];
|
||||
|
||||
const boolList& slaveFlip =
|
||||
faceZones[slaveFaceZoneID_.index()].flipMap();
|
||||
|
||||
slaveFaceCellsPtr_ = new labelList(slavePatchFaces.size());
|
||||
labelList& sfc = *slaveFaceCellsPtr_;
|
||||
|
||||
forAll(slavePatchFaces, faceI)
|
||||
{
|
||||
if (slaveFlip[faceI])
|
||||
{
|
||||
sfc[faceI] = nei[slavePatchFaces[faceI]];
|
||||
}
|
||||
else
|
||||
{
|
||||
sfc[faceI] = own[slavePatchFaces[faceI]];
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the addressing is valid
|
||||
if (min(mfc) < 0 || min(sfc) < 0)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
forAll(mfc, faceI)
|
||||
{
|
||||
if (mfc[faceI] < 0)
|
||||
{
|
||||
Pout<< "No cell next to master patch face " << faceI
|
||||
<< ". Global face no: " << mfc[faceI]
|
||||
<< " own: " << own[masterPatchFaces[faceI]]
|
||||
<< " nei: " << nei[masterPatchFaces[faceI]]
|
||||
<< " flip: " << masterFlip[faceI] << endl;
|
||||
}
|
||||
}
|
||||
|
||||
forAll(sfc, faceI)
|
||||
{
|
||||
if (sfc[faceI] < 0)
|
||||
{
|
||||
Pout<< "No cell next to slave patch face " << faceI
|
||||
<< ". Global face no: " << sfc[faceI]
|
||||
<< " own: " << own[slavePatchFaces[faceI]]
|
||||
<< " nei: " << nei[slavePatchFaces[faceI]]
|
||||
<< " flip: " << slaveFlip[faceI] << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FatalErrorIn
|
||||
(
|
||||
"void slidingInterface::calcAttachedAddressing()"
|
||||
"const"
|
||||
) << "Error is zone face-cell addressing. Probable error in "
|
||||
<< "decoupled mesh or sliding interface definition."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Calculate stick-out faces
|
||||
const labelListList& pointFaces = mesh.pointFaces();
|
||||
|
||||
// Master side
|
||||
labelHashSet masterStickOutFaceMap
|
||||
(
|
||||
primitiveMesh::facesPerCell_*(masterPatch.size())
|
||||
);
|
||||
|
||||
const labelList& masterMeshPoints = masterPatch.meshPoints();
|
||||
|
||||
forAll(masterMeshPoints, pointI)
|
||||
{
|
||||
const labelList& curFaces = pointFaces[masterMeshPoints[pointI]];
|
||||
|
||||
forAll(curFaces, faceI)
|
||||
{
|
||||
// Check if the face belongs to the master face zone;
|
||||
// if not add it
|
||||
if
|
||||
(
|
||||
faceZones.whichZone(curFaces[faceI])
|
||||
!= masterFaceZoneID_.index()
|
||||
)
|
||||
{
|
||||
masterStickOutFaceMap.insert(curFaces[faceI]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
masterStickOutFacesPtr_ = new labelList(masterStickOutFaceMap.toc());
|
||||
|
||||
// Slave side
|
||||
labelHashSet slaveStickOutFaceMap
|
||||
(
|
||||
primitiveMesh::facesPerCell_*(slavePatch.size())
|
||||
);
|
||||
|
||||
const labelList& slaveMeshPoints = slavePatch.meshPoints();
|
||||
|
||||
forAll(slaveMeshPoints, pointI)
|
||||
{
|
||||
const labelList& curFaces = pointFaces[slaveMeshPoints[pointI]];
|
||||
|
||||
forAll(curFaces, faceI)
|
||||
{
|
||||
// Check if the face belongs to the slave face zone;
|
||||
// if not add it
|
||||
if
|
||||
(
|
||||
faceZones.whichZone(curFaces[faceI])
|
||||
!= slaveFaceZoneID_.index()
|
||||
)
|
||||
{
|
||||
slaveStickOutFaceMap.insert(curFaces[faceI]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
slaveStickOutFacesPtr_ = new labelList(slaveStickOutFaceMap.toc());
|
||||
|
||||
|
||||
// Retired point addressing does not exist at this stage.
|
||||
// It will be filled when the interface is coupled.
|
||||
retiredPointMapPtr_ =
|
||||
new Map<label>
|
||||
(
|
||||
2*faceZones[slaveFaceZoneID_.index()]().nPoints()
|
||||
);
|
||||
|
||||
// Ditto for cut point edge map. This is a rough guess of its size
|
||||
//
|
||||
cutPointEdgePairMapPtr_ =
|
||||
new Map<Pair<edge> >
|
||||
(
|
||||
faceZones[slaveFaceZoneID_.index()]().nEdges()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void slidingInterface::calcAttachedAddressing() const"
|
||||
) << "The interface is attached. The zone face-cell addressing "
|
||||
<< "cannot be assembled for object " << name()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "void Foam::slidingInterface::calcAttachedAddressing() const "
|
||||
<< " for object " << name() << " : "
|
||||
<< "Finished calculating zone face-cell addressing."
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::slidingInterface::clearAttachedAddressing() const
|
||||
{
|
||||
deleteDemandDrivenData(masterFaceCellsPtr_);
|
||||
deleteDemandDrivenData(slaveFaceCellsPtr_);
|
||||
|
||||
deleteDemandDrivenData(masterStickOutFacesPtr_);
|
||||
deleteDemandDrivenData(slaveStickOutFacesPtr_);
|
||||
|
||||
deleteDemandDrivenData(retiredPointMapPtr_);
|
||||
deleteDemandDrivenData(cutPointEdgePairMapPtr_);
|
||||
}
|
||||
|
||||
|
||||
void Foam::slidingInterface::renumberAttachedAddressing
|
||||
(
|
||||
const mapPolyMesh& m
|
||||
) const
|
||||
{
|
||||
// Get reference to reverse cell renumbering
|
||||
// The renumbering map is needed the other way around, i.e. giving
|
||||
// the new cell number for every old cell next to the interface.
|
||||
const labelList& reverseCellMap = m.reverseCellMap();
|
||||
|
||||
const labelList& mfc = masterFaceCells();
|
||||
const labelList& sfc = slaveFaceCells();
|
||||
|
||||
// Master side
|
||||
labelList* newMfcPtr = new labelList(mfc.size(), -1);
|
||||
labelList& newMfc = *newMfcPtr;
|
||||
|
||||
const labelList& mfzRenumber =
|
||||
m.faceZoneFaceMap()[masterFaceZoneID_.index()];
|
||||
|
||||
forAll(mfc, faceI)
|
||||
{
|
||||
label newCellI = reverseCellMap[mfc[mfzRenumber[faceI]]];
|
||||
|
||||
if (newCellI >= 0)
|
||||
{
|
||||
newMfc[faceI] = newCellI;
|
||||
}
|
||||
}
|
||||
|
||||
// Slave side
|
||||
labelList* newSfcPtr = new labelList(sfc.size(), -1);
|
||||
labelList& newSfc = *newSfcPtr;
|
||||
|
||||
const labelList& sfzRenumber =
|
||||
m.faceZoneFaceMap()[slaveFaceZoneID_.index()];
|
||||
|
||||
forAll(sfc, faceI)
|
||||
{
|
||||
label newCellI = reverseCellMap[sfc[sfzRenumber[faceI]]];
|
||||
|
||||
if (newCellI >= 0)
|
||||
{
|
||||
newSfc[faceI] = newCellI;
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
// Check if all the mapped cells are live
|
||||
if (min(newMfc) < 0 || min(newSfc) < 0)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void slidingInterface::renumberAttachedAddressing("
|
||||
"const mapPolyMesh& m) const"
|
||||
) << "Error in cell renumbering for object " << name()
|
||||
<< ". Some of master cells next "
|
||||
<< "to the interface have been removed."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
// Renumber stick-out faces
|
||||
|
||||
const labelList& reverseFaceMap = m.reverseFaceMap();
|
||||
|
||||
// Master side
|
||||
const labelList& msof = masterStickOutFaces();
|
||||
|
||||
labelList* newMsofPtr = new labelList(msof.size(), -1);
|
||||
labelList& newMsof = *newMsofPtr;
|
||||
|
||||
forAll(msof, faceI)
|
||||
{
|
||||
label newFaceI = reverseFaceMap[msof[faceI]];
|
||||
|
||||
if (newFaceI >= 0)
|
||||
{
|
||||
newMsof[faceI] = newFaceI;
|
||||
}
|
||||
}
|
||||
// Pout<< "newMsof: " << newMsof << endl;
|
||||
// Slave side
|
||||
const labelList& ssof = slaveStickOutFaces();
|
||||
|
||||
labelList* newSsofPtr = new labelList(ssof.size(), -1);
|
||||
labelList& newSsof = *newSsofPtr;
|
||||
|
||||
forAll(ssof, faceI)
|
||||
{
|
||||
label newFaceI = reverseFaceMap[ssof[faceI]];
|
||||
|
||||
if (newFaceI >= 0)
|
||||
{
|
||||
newSsof[faceI] = newFaceI;
|
||||
}
|
||||
}
|
||||
// Pout<< "newSsof: " << newSsof << endl;
|
||||
if (debug)
|
||||
{
|
||||
// Check if all the mapped cells are live
|
||||
if (min(newMsof) < 0 || min(newSsof) < 0)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void slidingInterface::renumberAttachedAddressing("
|
||||
"const mapPolyMesh& m) const"
|
||||
) << "Error in face renumbering for object " << name()
|
||||
<< ". Some of stick-out next "
|
||||
<< "to the interface have been removed."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
// Renumber the retired point map. Need to take a copy!
|
||||
const Map<label> rpm = retiredPointMap();
|
||||
|
||||
Map<label>* newRpmPtr = new Map<label>(rpm.size());
|
||||
Map<label>& newRpm = *newRpmPtr;
|
||||
|
||||
const labelList rpmToc = rpm.toc();
|
||||
|
||||
// Get reference to point renumbering
|
||||
const labelList& reversePointMap = m.reversePointMap();
|
||||
|
||||
label key, value;
|
||||
|
||||
forAll(rpmToc, rpmTocI)
|
||||
{
|
||||
key = reversePointMap[rpmToc[rpmTocI]];
|
||||
|
||||
value = reversePointMap[rpm.find(rpmToc[rpmTocI])()];
|
||||
|
||||
if (debug)
|
||||
{
|
||||
// Check if all the mapped cells are live
|
||||
if (key < 0 || value < 0)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void slidingInterface::renumberAttachedAddressing("
|
||||
"const mapPolyMesh& m) const"
|
||||
) << "Error in retired point numbering for object "
|
||||
<< name() << ". Some of master "
|
||||
<< "points have been removed."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
newRpm.insert(key, value);
|
||||
}
|
||||
|
||||
// Renumber the cut point edge pair map. Need to take a copy!
|
||||
const Map<Pair<edge> > cpepm = cutPointEdgePairMap();
|
||||
|
||||
Map<Pair<edge> >* newCpepmPtr = new Map<Pair<edge> >(cpepm.size());
|
||||
Map<Pair<edge> >& newCpepm = *newCpepmPtr;
|
||||
|
||||
const labelList cpepmToc = cpepm.toc();
|
||||
|
||||
forAll(cpepmToc, cpepmTocI)
|
||||
{
|
||||
key = reversePointMap[cpepmToc[cpepmTocI]];
|
||||
|
||||
const Pair<edge>& oldPe = cpepm.find(cpepmToc[cpepmTocI])();
|
||||
|
||||
// Re-do the edges in global addressing
|
||||
const label ms = reversePointMap[oldPe.first().start()];
|
||||
const label me = reversePointMap[oldPe.first().end()];
|
||||
|
||||
const label ss = reversePointMap[oldPe.second().start()];
|
||||
const label se = reversePointMap[oldPe.second().end()];
|
||||
|
||||
if (debug)
|
||||
{
|
||||
// Check if all the mapped cells are live
|
||||
if (key < 0 || ms < 0 || me < 0 || ss < 0 || se < 0)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void slidingInterface::renumberAttachedAddressing("
|
||||
"const mapPolyMesh& m) const"
|
||||
) << "Error in cut point edge pair map numbering for object "
|
||||
<< name() << ". Some of master points have been removed."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
newCpepm.insert(key, Pair<edge>(edge(ms, me), edge(ss, se)));
|
||||
}
|
||||
|
||||
if (!projectedSlavePointsPtr_)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void slidingInterface::renumberAttachedAddressing("
|
||||
"const mapPolyMesh& m) const"
|
||||
) << "Error in projected point numbering for object " << name()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Renumber the projected slave zone points
|
||||
const pointField& projectedSlavePoints = *projectedSlavePointsPtr_;
|
||||
|
||||
pointField* newProjectedSlavePointsPtr
|
||||
(
|
||||
new pointField(projectedSlavePoints.size())
|
||||
);
|
||||
pointField& newProjectedSlavePoints = *newProjectedSlavePointsPtr;
|
||||
|
||||
const labelList& sfzPointRenumber =
|
||||
m.faceZonePointMap()[slaveFaceZoneID_.index()];
|
||||
|
||||
forAll(newProjectedSlavePoints, pointI)
|
||||
{
|
||||
if (sfzPointRenumber[pointI] > -1)
|
||||
{
|
||||
newProjectedSlavePoints[pointI] =
|
||||
projectedSlavePoints[sfzPointRenumber[pointI]];
|
||||
}
|
||||
}
|
||||
|
||||
// Re-set the lists
|
||||
clearAttachedAddressing();
|
||||
|
||||
deleteDemandDrivenData(projectedSlavePointsPtr_);
|
||||
|
||||
masterFaceCellsPtr_ = newMfcPtr;
|
||||
slaveFaceCellsPtr_ = newSfcPtr;
|
||||
|
||||
masterStickOutFacesPtr_ = newMsofPtr;
|
||||
slaveStickOutFacesPtr_ = newSsofPtr;
|
||||
|
||||
retiredPointMapPtr_ = newRpmPtr;
|
||||
cutPointEdgePairMapPtr_ = newCpepmPtr;
|
||||
projectedSlavePointsPtr_ = newProjectedSlavePointsPtr;
|
||||
}
|
||||
|
||||
|
||||
const Foam::labelList& Foam::slidingInterface::masterFaceCells() const
|
||||
{
|
||||
if (!masterFaceCellsPtr_)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"const labelList& slidingInterface::masterFaceCells() const"
|
||||
) << "Master zone face-cell addressing not available for object "
|
||||
<< name()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return *masterFaceCellsPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::labelList& Foam::slidingInterface::slaveFaceCells() const
|
||||
{
|
||||
if (!slaveFaceCellsPtr_)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"const labelList& slidingInterface::slaveFaceCells() const"
|
||||
) << "Slave zone face-cell addressing not available for object "
|
||||
<< name()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return *slaveFaceCellsPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::labelList& Foam::slidingInterface::masterStickOutFaces() const
|
||||
{
|
||||
if (!masterStickOutFacesPtr_)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"const labelList& slidingInterface::masterStickOutFaces() const"
|
||||
) << "Master zone stick-out face addressing not available for object "
|
||||
<< name()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return *masterStickOutFacesPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::labelList& Foam::slidingInterface::slaveStickOutFaces() const
|
||||
{
|
||||
if (!slaveStickOutFacesPtr_)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"const labelList& slidingInterface::slaveStickOutFaces() const"
|
||||
) << "Slave zone stick-out face addressing not available for object "
|
||||
<< name()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return *slaveStickOutFacesPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::Map<Foam::label>& Foam::slidingInterface::retiredPointMap() const
|
||||
{
|
||||
if (!retiredPointMapPtr_)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"const Map<label>& slidingInterface::retiredPointMap() const"
|
||||
) << "Retired point map not available for object " << name()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return *retiredPointMapPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::Map<Foam::Pair<Foam::edge> >&
|
||||
Foam::slidingInterface::cutPointEdgePairMap() const
|
||||
{
|
||||
if (!cutPointEdgePairMapPtr_)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"const Map<Pair<edge> >& slidingInterface::"
|
||||
"cutPointEdgePairMap() const"
|
||||
) << "Retired point map not available for object " << name()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return *cutPointEdgePairMapPtr_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,77 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "slidingInterface.H"
|
||||
#include "polyTopoChange.H"
|
||||
#include "polyMesh.H"
|
||||
#include "polyTopoChanger.H"
|
||||
#include "polyRemovePoint.H"
|
||||
#include "polyRemoveFace.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::slidingInterface::clearCouple
|
||||
(
|
||||
polyTopoChange& ref
|
||||
) const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "void slidingInterface::clearCouple("
|
||||
<< "polyTopoChange& ref) const for object " << name() << " : "
|
||||
<< "Clearing old couple points and faces." << endl;
|
||||
}
|
||||
|
||||
// Remove all points from the point zone
|
||||
|
||||
const polyMesh& mesh = topoChanger().mesh();
|
||||
|
||||
const labelList& cutPointZoneLabels =
|
||||
mesh.pointZones()[cutPointZoneID_.index()];
|
||||
|
||||
forAll(cutPointZoneLabels, pointI)
|
||||
{
|
||||
ref.setAction(polyRemovePoint(cutPointZoneLabels[pointI]));
|
||||
}
|
||||
|
||||
// Remove all faces from the face zone
|
||||
const labelList& cutFaceZoneLabels =
|
||||
mesh.faceZones()[cutFaceZoneID_.index()];
|
||||
|
||||
forAll(cutFaceZoneLabels, faceI)
|
||||
{
|
||||
ref.setAction(polyRemoveFace(cutFaceZoneLabels[faceI]));
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "void slidingInterface::clearCouple("
|
||||
<< "polyTopoChange& ref) const for object " << name() << " : "
|
||||
<< "Finished clearing old couple points and faces." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
1273
src/dynamicMesh/slidingInterface/slidingInterfaceProjectPoints.C
Normal file
1273
src/dynamicMesh/slidingInterface/slidingInterfaceProjectPoints.C
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user