mirror of
https://github.com/OpenFOAM/OpenFOAM-6.git
synced 2025-12-08 06:57:46 +00:00
Add the OpenFOAM source tree
This commit is contained in:
490
src/dynamicMesh/attachDetach/detachInterface.C
Normal file
490
src/dynamicMesh/attachDetach/detachInterface.C
Normal file
@ -0,0 +1,490 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "attachDetach.H"
|
||||
#include "polyMesh.H"
|
||||
#include "primitiveMesh.H"
|
||||
#include "polyTopoChange.H"
|
||||
#include "polyTopoChanger.H"
|
||||
#include "polyAddPoint.H"
|
||||
#include "polyModifyFace.H"
|
||||
#include "polyAddFace.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::attachDetach::detachInterface
|
||||
(
|
||||
polyTopoChange& ref
|
||||
) const
|
||||
{
|
||||
// Algorithm:
|
||||
// 1. Create new points for points of the master face zone
|
||||
// 2. Modify all faces of the master zone, by putting them into the master
|
||||
// patch (look for orientation) and their renumbered mirror images
|
||||
// into the slave patch
|
||||
// 3. Create a point renumbering list, giving a new point index for original
|
||||
// points in the face patch
|
||||
// 4. Grab all faces in cells on the master side and renumber them
|
||||
// using the point renumbering list. Exclude the ones that belong to
|
||||
// the master face zone
|
||||
//
|
||||
// Note on point creation:
|
||||
// In order to take into account the issues related to partial
|
||||
// blocking in an attach/detach mesh modifier, special treatment
|
||||
// is required for the duplication of points on the edge of the
|
||||
// face zone. Points which are shared only by internal edges need
|
||||
// not to be duplicated, as this would propagate the discontinuity
|
||||
// in the mesh beyond the face zone. Therefore, before creating
|
||||
// the new points, check the external edge loop. For each edge
|
||||
// check if the edge is internal (i.e. does not belong to a
|
||||
// patch); if so, exclude both of its points from duplication.
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "void attachDetach::detachInterface("
|
||||
<< "polyTopoChange& ref) const "
|
||||
<< " for object " << name() << " : "
|
||||
<< "Detaching interface" << endl;
|
||||
}
|
||||
|
||||
const polyMesh& mesh = topoChanger().mesh();
|
||||
const faceZoneMesh& zoneMesh = mesh.faceZones();
|
||||
|
||||
// Check that zone is in increasing order (needed since adding faces
|
||||
// in same order - otherwise polyTopoChange face ordering will mess up
|
||||
// correspondence)
|
||||
if (debug)
|
||||
{
|
||||
const labelList& faceLabels = zoneMesh[faceZoneID_.index()];
|
||||
if (faceLabels.size() > 0)
|
||||
{
|
||||
for (label i = 1; i < faceLabels.size(); i++)
|
||||
{
|
||||
if (faceLabels[i] <= faceLabels[i-1])
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"attachDetach::detachInterface"
|
||||
"(polyTopoChange&) const"
|
||||
) << "faceZone " << zoneMesh[faceZoneID_.index()].name()
|
||||
<< " does not have mesh face labels in"
|
||||
<< " increasing order." << endl
|
||||
<< "Face label " << faceLabels[i]
|
||||
<< " at position " << i
|
||||
<< " is smaller than the previous value "
|
||||
<< faceLabels[i-1]
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const primitiveFacePatch& masterFaceLayer = zoneMesh[faceZoneID_.index()]();
|
||||
const pointField& points = mesh.points();
|
||||
const labelListList& meshEdgeFaces = mesh.edgeFaces();
|
||||
|
||||
const labelList& mp = masterFaceLayer.meshPoints();
|
||||
const edgeList& zoneLocalEdges = masterFaceLayer.edges();
|
||||
|
||||
const labelList& meshEdges = zoneMesh[faceZoneID_.index()].meshEdges();
|
||||
|
||||
// Create the points
|
||||
|
||||
labelList addedPoints(mp.size(), -1);
|
||||
|
||||
// Go through boundary edges of the master patch. If all the faces from
|
||||
// this patch are internal, mark the points in the addedPoints lookup
|
||||
// with their original labels to stop duplication
|
||||
label nIntEdges = masterFaceLayer.nInternalEdges();
|
||||
|
||||
for (label curEdgeID = nIntEdges; curEdgeID < meshEdges.size(); curEdgeID++)
|
||||
{
|
||||
const labelList& curFaces = meshEdgeFaces[meshEdges[curEdgeID]];
|
||||
|
||||
bool edgeIsInternal = true;
|
||||
|
||||
forAll(curFaces, faceI)
|
||||
{
|
||||
if (!mesh.isInternalFace(curFaces[faceI]))
|
||||
{
|
||||
// The edge belongs to a boundary face
|
||||
edgeIsInternal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (edgeIsInternal)
|
||||
{
|
||||
const edge& e = zoneLocalEdges[curEdgeID];
|
||||
|
||||
// Reset the point creation
|
||||
addedPoints[e.start()] = mp[e.start()];
|
||||
addedPoints[e.end()] = mp[e.end()];
|
||||
}
|
||||
}
|
||||
// Pout<< "addedPoints before point creation: " << addedPoints << endl;
|
||||
|
||||
// Create new points for face zone
|
||||
forAll(addedPoints, pointI)
|
||||
{
|
||||
if (addedPoints[pointI] < 0)
|
||||
{
|
||||
addedPoints[pointI] =
|
||||
ref.setAction
|
||||
(
|
||||
polyAddPoint
|
||||
(
|
||||
points[mp[pointI]], // point
|
||||
mp[pointI], // master point
|
||||
-1, // zone ID
|
||||
true // supports a cell
|
||||
)
|
||||
);
|
||||
//Pout<< "Adding point " << addedPoints[pointI]
|
||||
// << " coord1:" << points[mp[pointI]]
|
||||
// << " coord2:" << masterFaceLayer.localPoints()[pointI]
|
||||
// << " for original point " << mp[pointI] << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Modify faces in the master zone and duplicate for the slave zone
|
||||
|
||||
const labelList& mf = zoneMesh[faceZoneID_.index()];
|
||||
const boolList& mfFlip = zoneMesh[faceZoneID_.index()].flipMap();
|
||||
const faceList& zoneFaces = masterFaceLayer.localFaces();
|
||||
|
||||
const faceList& faces = mesh.faces();
|
||||
const labelList& own = mesh.faceOwner();
|
||||
const labelList& nei = mesh.faceNeighbour();
|
||||
|
||||
forAll(mf, faceI)
|
||||
{
|
||||
const label curFaceID = mf[faceI];
|
||||
|
||||
// Build the face for the slave patch by renumbering
|
||||
const face oldFace = zoneFaces[faceI].reverseFace();
|
||||
|
||||
face newFace(oldFace.size());
|
||||
|
||||
forAll(oldFace, pointI)
|
||||
{
|
||||
newFace[pointI] = addedPoints[oldFace[pointI]];
|
||||
}
|
||||
|
||||
if (mfFlip[faceI])
|
||||
{
|
||||
// Face needs to be flipped for the master patch
|
||||
ref.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
faces[curFaceID].reverseFace(), // modified face
|
||||
curFaceID, // label of face being modified
|
||||
nei[curFaceID], // owner
|
||||
-1, // neighbour
|
||||
true, // face flip
|
||||
masterPatchID_.index(), // patch for face
|
||||
false, // remove from zone
|
||||
faceZoneID_.index(), // zone for face
|
||||
!mfFlip[faceI] // face flip in zone
|
||||
)
|
||||
);
|
||||
|
||||
// Add renumbered face into the slave patch
|
||||
//label addedFaceI =
|
||||
ref.setAction
|
||||
(
|
||||
polyAddFace
|
||||
(
|
||||
newFace, // face
|
||||
own[curFaceID], // owner
|
||||
-1, // neighbour
|
||||
-1, // master point
|
||||
-1, // master edge
|
||||
curFaceID, // master face
|
||||
false, // flip flux
|
||||
slavePatchID_.index(), // patch to add the face to
|
||||
-1, // zone for face
|
||||
false // zone flip
|
||||
)
|
||||
);
|
||||
//{
|
||||
// pointField newPts(ref.points());
|
||||
//Pout<< "Flip. Modifying face: " << ref.faces()[curFaceID]
|
||||
// << " fc:" << ref.faces()[curFaceID].centre(newPts)
|
||||
// << " next to cell: " << nei[curFaceID]
|
||||
// << " and adding face: " << newFace
|
||||
// << " fc:" << ref.faces()[addedFaceI].centre(newPts)
|
||||
// << " next to cell: " << own[curFaceID] << endl;
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No flip
|
||||
ref.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
faces[curFaceID], // modified face
|
||||
curFaceID, // label of face being modified
|
||||
own[curFaceID], // owner
|
||||
-1, // neighbour
|
||||
false, // face flip
|
||||
masterPatchID_.index(), // patch for face
|
||||
false, // remove from zone
|
||||
faceZoneID_.index(), // zone for face
|
||||
mfFlip[faceI] // face flip in zone
|
||||
)
|
||||
);
|
||||
|
||||
// Add renumbered face into the slave patch
|
||||
//label addedFaceI =
|
||||
ref.setAction
|
||||
(
|
||||
polyAddFace
|
||||
(
|
||||
newFace, // face
|
||||
nei[curFaceID], // owner
|
||||
-1, // neighbour
|
||||
-1, // master point
|
||||
-1, // master edge
|
||||
curFaceID, // master face
|
||||
true, // flip flux
|
||||
slavePatchID_.index(), // patch to add the face to
|
||||
-1, // zone for face
|
||||
false // face flip in zone
|
||||
)
|
||||
);
|
||||
//{
|
||||
// pointField newPts(ref.points());
|
||||
//Pout<< "No flip. Modifying face: " << ref.faces()[curFaceID]
|
||||
// << " fc:" << ref.faces()[curFaceID].centre(newPts)
|
||||
// << " next to cell: " << own[curFaceID]
|
||||
// << " and adding face: " << newFace
|
||||
// << " fc:" << ref.faces()[addedFaceI].centre(newPts)
|
||||
// << " next to cell: " << nei[curFaceID] << endl;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
// Modify the remaining faces of the master cells to reconnect to the new
|
||||
// layer of faces.
|
||||
|
||||
// Algorithm: Go through all the cells of the master zone and make
|
||||
// a map of faces to avoid duplicates. Do not insert the faces in
|
||||
// the master patch (as they have already been dealt with). Make
|
||||
// a master layer point renumbering map, which for every point in
|
||||
// the master layer gives its new label. Loop through all faces in
|
||||
// the map and attempt to renumber them using the master layer
|
||||
// point renumbering map. Once the face is renumbered, compare it
|
||||
// with the original face; if they are the same, the face has not
|
||||
// changed; if not, modify the face but keep all of its old
|
||||
// attributes (apart from the vertex numbers).
|
||||
|
||||
// Create the map of faces in the master cell layer
|
||||
const labelList& mc =
|
||||
mesh.faceZones()[faceZoneID_.index()].masterCells();
|
||||
|
||||
labelHashSet masterCellFaceMap(6*mc.size());
|
||||
|
||||
const cellList& cells = mesh.cells();
|
||||
|
||||
forAll(mc, cellI)
|
||||
{
|
||||
const labelList& curFaces = cells[mc[cellI]];
|
||||
|
||||
forAll(curFaces, faceI)
|
||||
{
|
||||
// Check if the face belongs to the master patch; if not add it
|
||||
if (zoneMesh.whichZone(curFaces[faceI]) != faceZoneID_.index())
|
||||
{
|
||||
masterCellFaceMap.insert(curFaces[faceI]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extend the map to include first neighbours of the master cells to
|
||||
// deal with multiple corners.
|
||||
{ // Protection and memory management
|
||||
// Make a map of master cells for quick reject
|
||||
labelHashSet mcMap(2*mc.size());
|
||||
|
||||
forAll(mc, mcI)
|
||||
{
|
||||
mcMap.insert(mc[mcI]);
|
||||
}
|
||||
|
||||
// Go through all the faces in the masterCellFaceMap. If the
|
||||
// cells around them are not already used, add all of their
|
||||
// faces to the map
|
||||
const labelList mcf = masterCellFaceMap.toc();
|
||||
|
||||
forAll(mcf, mcfI)
|
||||
{
|
||||
// Do the owner side
|
||||
const label ownCell = own[mcf[mcfI]];
|
||||
|
||||
if (!mcMap.found(ownCell))
|
||||
{
|
||||
// Cell not found. Add its faces to the map
|
||||
const cell& curFaces = cells[ownCell];
|
||||
|
||||
forAll(curFaces, faceI)
|
||||
{
|
||||
masterCellFaceMap.insert(curFaces[faceI]);
|
||||
}
|
||||
}
|
||||
|
||||
// Do the neighbour side if face is internal
|
||||
if (mesh.isInternalFace(mcf[mcfI]))
|
||||
{
|
||||
const label neiCell = nei[mcf[mcfI]];
|
||||
|
||||
if (!mcMap.found(neiCell))
|
||||
{
|
||||
// Cell not found. Add its faces to the map
|
||||
const cell& curFaces = cells[neiCell];
|
||||
|
||||
forAll(curFaces, faceI)
|
||||
{
|
||||
masterCellFaceMap.insert(curFaces[faceI]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the master layer point map
|
||||
Map<label> masterLayerPointMap(2*mp.size());
|
||||
|
||||
forAll(mp, pointI)
|
||||
{
|
||||
masterLayerPointMap.insert
|
||||
(
|
||||
mp[pointI],
|
||||
addedPoints[pointI]
|
||||
);
|
||||
}
|
||||
|
||||
// Grab the list of faces of the master layer
|
||||
const labelList masterCellFaces = masterCellFaceMap.toc();
|
||||
|
||||
forAll(masterCellFaces, faceI)
|
||||
{
|
||||
// Attempt to renumber the face using the masterLayerPointMap.
|
||||
// Missing point remain the same
|
||||
|
||||
const label curFaceID = masterCellFaces[faceI];
|
||||
|
||||
const face& oldFace = faces[curFaceID];
|
||||
|
||||
face newFace(oldFace.size());
|
||||
|
||||
bool changed = false;
|
||||
|
||||
forAll(oldFace, pointI)
|
||||
{
|
||||
if (masterLayerPointMap.found(oldFace[pointI]))
|
||||
{
|
||||
changed = true;
|
||||
|
||||
newFace[pointI] = masterLayerPointMap.find(oldFace[pointI])();
|
||||
}
|
||||
else
|
||||
{
|
||||
newFace[pointI] = oldFace[pointI];
|
||||
}
|
||||
}
|
||||
|
||||
// If the face has changed, create a modification entry
|
||||
if (changed)
|
||||
{
|
||||
if (mesh.isInternalFace(curFaceID))
|
||||
{
|
||||
ref.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
newFace, // face
|
||||
curFaceID, // master face
|
||||
own[curFaceID], // owner
|
||||
nei[curFaceID], // neighbour
|
||||
false, // flip flux
|
||||
-1, // patch for face
|
||||
false, // remove from zone
|
||||
-1, // zone for face
|
||||
false // face zone flip
|
||||
)
|
||||
);
|
||||
|
||||
// Pout<< "modifying stick-out face. Internal Old face: "
|
||||
// << oldFace
|
||||
// << " new face: " << newFace
|
||||
// << " own: " << own[curFaceID]
|
||||
// << " nei: " << nei[curFaceID]
|
||||
// << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
ref.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
newFace, // face
|
||||
curFaceID, // master face
|
||||
own[curFaceID], // owner
|
||||
-1, // neighbour
|
||||
false, // flip flux
|
||||
mesh.boundaryMesh().whichPatch(curFaceID), // patch
|
||||
false, // remove from zone
|
||||
-1, // zone for face
|
||||
false // face zone flip
|
||||
)
|
||||
);
|
||||
|
||||
// Pout<< "modifying stick-out face. Boundary Old face: "
|
||||
// << oldFace
|
||||
// << " new face: " << newFace
|
||||
// << " own: " << own[curFaceID]
|
||||
// << " patch: "
|
||||
// << mesh.boundaryMesh().whichPatch(curFaceID)
|
||||
// << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "void attachDetach::detachInterface("
|
||||
<< "polyTopoChange& ref) const "
|
||||
<< " for object " << name() << " : "
|
||||
<< "Finished detaching interface" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user