mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
extrudeMesh does extrusion from existing mesh
This commit is contained in:
@ -38,6 +38,7 @@ Description
|
||||
#include "polyModifyFace.H"
|
||||
#include "polyRemovePoint.H"
|
||||
#include "polyRemoveFace.H"
|
||||
#include "indirectPrimitivePatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
@ -61,7 +62,7 @@ const Foam::scalar Foam::perfectInterface::tol_ = 1E-3;
|
||||
|
||||
Foam::pointField Foam::perfectInterface::calcFaceCentres
|
||||
(
|
||||
const primitivePatch& pp
|
||||
const indirectPrimitivePatch& pp
|
||||
)
|
||||
{
|
||||
const pointField& points = pp.points();
|
||||
@ -155,6 +156,295 @@ bool Foam::perfectInterface::changeTopology() const
|
||||
}
|
||||
|
||||
|
||||
void Foam::perfectInterface::setRefinement
|
||||
(
|
||||
const indirectPrimitivePatch& pp0,
|
||||
const indirectPrimitivePatch& pp1,
|
||||
polyTopoChange& ref
|
||||
) const
|
||||
{
|
||||
const polyMesh& mesh = topoChanger().mesh();
|
||||
|
||||
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||
|
||||
// Some aliases
|
||||
const edgeList& edges0 = pp0.edges();
|
||||
const pointField& pts0 = pp0.localPoints();
|
||||
const pointField& pts1 = pp1.localPoints();
|
||||
const labelList& meshPts0 = pp0.meshPoints();
|
||||
const labelList& meshPts1 = pp1.meshPoints();
|
||||
|
||||
|
||||
// Get local dimension as fraction of minimum edge length
|
||||
|
||||
scalar minLen = GREAT;
|
||||
|
||||
forAll(edges0, edgeI)
|
||||
{
|
||||
minLen = min(minLen, edges0[edgeI].mag(pts0));
|
||||
}
|
||||
scalar typDim = tol_*minLen;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "typDim:" << typDim << " edges0:" << edges0.size()
|
||||
<< " pts0:" << pts0.size() << " pts1:" << pts1.size()
|
||||
<< " pp0:" << pp0.size() << " pp1:" << pp1.size() << endl;
|
||||
}
|
||||
|
||||
|
||||
// Determine pointMapping in mesh point labels. Uses geometric
|
||||
// comparison to find correspondence between patch points.
|
||||
|
||||
labelList renumberPoints(mesh.points().size());
|
||||
forAll(renumberPoints, i)
|
||||
{
|
||||
renumberPoints[i] = i;
|
||||
}
|
||||
{
|
||||
labelList from1To0Points(pts1.size());
|
||||
|
||||
bool matchOk = matchPoints
|
||||
(
|
||||
pts1,
|
||||
pts0,
|
||||
scalarField(pts1.size(), typDim), // tolerance
|
||||
true, // verbose
|
||||
from1To0Points
|
||||
);
|
||||
|
||||
if (!matchOk)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"perfectInterface::setRefinement(polyTopoChange& ref) const"
|
||||
) << "Points on patch sides do not match to within tolerance "
|
||||
<< typDim << exit(FatalError);
|
||||
}
|
||||
|
||||
forAll(pts1, i)
|
||||
{
|
||||
renumberPoints[meshPts1[i]] = meshPts0[from1To0Points[i]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Calculate correspondence between patch faces
|
||||
|
||||
labelList from0To1Faces(pp1.size());
|
||||
|
||||
bool matchOk = matchPoints
|
||||
(
|
||||
calcFaceCentres(pp0),
|
||||
calcFaceCentres(pp1),
|
||||
scalarField(pp0.size(), typDim), // tolerance
|
||||
true, // verbose
|
||||
from0To1Faces
|
||||
);
|
||||
|
||||
if (!matchOk)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"perfectInterface::setRefinement(polyTopoChange& ref) const"
|
||||
) << "Face centres of patch sides do not match to within tolerance "
|
||||
<< typDim << exit(FatalError);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Now
|
||||
// - renumber faces using pts1 (except patch1 faces)
|
||||
// - remove patch1 faces. Remember cell label on owner side.
|
||||
// - modify patch0 faces to be internal.
|
||||
|
||||
// 1. Get faces to be renumbered
|
||||
labelHashSet affectedFaces(2*pp1.size());
|
||||
forAll(meshPts1, i)
|
||||
{
|
||||
label meshPointI = meshPts1[i];
|
||||
|
||||
if (meshPointI != renumberPoints[meshPointI])
|
||||
{
|
||||
const labelList& pFaces = mesh.pointFaces()[meshPointI];
|
||||
|
||||
forAll(pFaces, pFaceI)
|
||||
{
|
||||
affectedFaces.insert(pFaces[pFaceI]);
|
||||
}
|
||||
}
|
||||
}
|
||||
forAll(pp1, i)
|
||||
{
|
||||
affectedFaces.erase(pp1.addressing()[i]);
|
||||
}
|
||||
// Remove patch0 from renumbered faces. Should not be nessecary since
|
||||
// patch0 and 1 should not share any point (if created by mergeMeshing)
|
||||
// so affectedFaces should not contain any patch0 faces but you can
|
||||
// never be sure what the user is doing.
|
||||
forAll(pp0, i)
|
||||
{
|
||||
label faceI = pp0.addressing()[i];
|
||||
|
||||
if (affectedFaces.erase(faceI))
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"perfectInterface::setRefinement(polyTopoChange&) const"
|
||||
) << "Found face " << faceI << " vertices "
|
||||
<< mesh.faces()[faceI] << " whose points are"
|
||||
<< " used both by master patch and slave patch" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 2. Renumber (non patch0/1) faces.
|
||||
for
|
||||
(
|
||||
labelHashSet::const_iterator iter = affectedFaces.begin();
|
||||
iter != affectedFaces.end();
|
||||
++iter
|
||||
)
|
||||
{
|
||||
label faceI = iter.key();
|
||||
|
||||
const face& f = mesh.faces()[faceI];
|
||||
|
||||
face newFace(f.size());
|
||||
|
||||
forAll(newFace, fp)
|
||||
{
|
||||
newFace[fp] = renumberPoints[f[fp]];
|
||||
}
|
||||
|
||||
label nbr = -1;
|
||||
|
||||
label patchI = -1;
|
||||
|
||||
if (mesh.isInternalFace(faceI))
|
||||
{
|
||||
nbr = mesh.faceNeighbour()[faceI];
|
||||
}
|
||||
else
|
||||
{
|
||||
patchI = patches.whichPatch(faceI);
|
||||
}
|
||||
|
||||
label zoneID = mesh.faceZones().whichZone(faceI);
|
||||
|
||||
bool zoneFlip = false;
|
||||
|
||||
if (zoneID >= 0)
|
||||
{
|
||||
const faceZone& fZone = mesh.faceZones()[zoneID];
|
||||
|
||||
zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
|
||||
}
|
||||
|
||||
ref.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
newFace, // modified face
|
||||
faceI, // label of face being modified
|
||||
mesh.faceOwner()[faceI], // owner
|
||||
nbr, // neighbour
|
||||
false, // face flip
|
||||
patchI, // patch for face
|
||||
false, // remove from zone
|
||||
zoneID, // zone for face
|
||||
zoneFlip // face flip in zone
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// 3. Remove patch1 points
|
||||
forAll(meshPts1, i)
|
||||
{
|
||||
label meshPointI = meshPts1[i];
|
||||
|
||||
if (meshPointI != renumberPoints[meshPointI])
|
||||
{
|
||||
ref.setAction(polyRemovePoint(meshPointI));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 4. Remove patch1 faces
|
||||
forAll(pp1, i)
|
||||
{
|
||||
label faceI = pp1.addressing()[i];
|
||||
ref.setAction(polyRemoveFace(faceI));
|
||||
}
|
||||
|
||||
|
||||
// 5. Modify patch0 faces for new points (not really nessecary; see
|
||||
// comment above about patch1 and patch0 never sharing points) and
|
||||
// becoming internal.
|
||||
const boolList& mfFlip =
|
||||
mesh.faceZones()[faceZoneID_.index()].flipMap();
|
||||
|
||||
forAll(pp0, i)
|
||||
{
|
||||
label faceI = pp0.addressing()[i];
|
||||
|
||||
const face& f = mesh.faces()[faceI];
|
||||
|
||||
face newFace(f.size());
|
||||
|
||||
forAll(newFace, fp)
|
||||
{
|
||||
newFace[fp] = renumberPoints[f[fp]];
|
||||
}
|
||||
|
||||
label own = mesh.faceOwner()[faceI];
|
||||
|
||||
label pp1FaceI = pp1.addressing()[from0To1Faces[i]];
|
||||
|
||||
label nbr = mesh.faceOwner()[pp1FaceI];
|
||||
|
||||
if (own < nbr)
|
||||
{
|
||||
ref.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
newFace, // modified face
|
||||
faceI, // label of face being modified
|
||||
own, // owner
|
||||
nbr, // neighbour
|
||||
false, // face flip
|
||||
-1, // patch for face
|
||||
false, // remove from zone
|
||||
faceZoneID_.index(), // zone for face
|
||||
mfFlip[i] // face flip in zone
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
ref.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
newFace.reverseFace(), // modified face
|
||||
faceI, // label of face being modified
|
||||
nbr, // owner
|
||||
own, // neighbour
|
||||
true, // face flip
|
||||
-1, // patch for face
|
||||
false, // remove from zone
|
||||
faceZoneID_.index(), // zone for face
|
||||
!mfFlip[i] // face flip in zone
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::perfectInterface::setRefinement(polyTopoChange& ref) const
|
||||
{
|
||||
if (debug)
|
||||
@ -176,286 +466,25 @@ void Foam::perfectInterface::setRefinement(polyTopoChange& ref) const
|
||||
const polyMesh& mesh = topoChanger().mesh();
|
||||
|
||||
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||
|
||||
const polyPatch& pp0 = patches[masterPatchID_.index()];
|
||||
const polyPatch& pp1 = patches[slavePatchID_.index()];
|
||||
|
||||
// Some aliases
|
||||
const edgeList& edges0 = pp0.edges();
|
||||
const pointField& pts0 = pp0.localPoints();
|
||||
const pointField& pts1 = pp1.localPoints();
|
||||
const labelList& meshPts0 = pp0.meshPoints();
|
||||
const labelList& meshPts1 = pp1.meshPoints();
|
||||
|
||||
|
||||
// Get local dimension as fraction of minimum edge length
|
||||
|
||||
scalar minLen = GREAT;
|
||||
|
||||
forAll(edges0, edgeI)
|
||||
{
|
||||
minLen = min(minLen, edges0[edgeI].mag(pts0));
|
||||
}
|
||||
scalar typDim = tol_*minLen;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "typDim:" << typDim << " edges0:" << edges0.size()
|
||||
<< " pts0:" << pts0.size() << " pts1:" << pts1.size()
|
||||
<< " pp0:" << pp0.size() << " pp1:" << pp1.size() << endl;
|
||||
}
|
||||
const polyPatch& patch0 = patches[masterPatchID_.index()];
|
||||
const polyPatch& patch1 = patches[slavePatchID_.index()];
|
||||
|
||||
|
||||
// Determine pointMapping in mesh point labels. Uses geometric
|
||||
// comparison to find correspondence between patch points.
|
||||
|
||||
labelList renumberPoints(mesh.points().size());
|
||||
forAll(renumberPoints, i)
|
||||
{
|
||||
renumberPoints[i] = i;
|
||||
}
|
||||
{
|
||||
labelList from1To0Points(pts1.size());
|
||||
|
||||
bool matchOk = matchPoints
|
||||
(
|
||||
pts1,
|
||||
pts0,
|
||||
scalarField(pts1.size(), typDim), // tolerance
|
||||
true, // verbose
|
||||
from1To0Points
|
||||
);
|
||||
|
||||
if (!matchOk)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"perfectInterface::setRefinement(polyTopoChange& ref) const"
|
||||
) << "Points on patches " << pp0.name() << " and "
|
||||
<< pp1.name() << " do not match to within tolerance "
|
||||
<< typDim << exit(FatalError);
|
||||
}
|
||||
|
||||
forAll(pts1, i)
|
||||
{
|
||||
renumberPoints[meshPts1[i]] = meshPts0[from1To0Points[i]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Calculate correspondence between patch faces
|
||||
|
||||
labelList from0To1Faces(pp1.size());
|
||||
|
||||
bool matchOk = matchPoints
|
||||
labelList pp0Labels(identity(patch0.size())+patch0.start());
|
||||
indirectPrimitivePatch pp0
|
||||
(
|
||||
calcFaceCentres(pp0),
|
||||
calcFaceCentres(pp1),
|
||||
scalarField(pp0.size(), typDim), // tolerance
|
||||
true, // verbose
|
||||
from0To1Faces
|
||||
IndirectList<face>(mesh.faces(), pp0Labels),
|
||||
mesh.points()
|
||||
);
|
||||
|
||||
if (!matchOk)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"perfectInterface::setRefinement(polyTopoChange& ref) const"
|
||||
) << "Face centres of patches " << pp0.name() << " and "
|
||||
<< pp1.name() << " do not match to within tolerance " << typDim
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Now
|
||||
// - renumber faces using pts1 (except patch1 faces)
|
||||
// - remove patch1 faces. Remember cell label on owner side.
|
||||
// - modify patch0 faces to be internal.
|
||||
|
||||
// 1. Get faces to be renumbered
|
||||
labelHashSet affectedFaces(2*pp1.size());
|
||||
forAll(meshPts1, i)
|
||||
{
|
||||
label meshPointI = meshPts1[i];
|
||||
|
||||
if (meshPointI != renumberPoints[meshPointI])
|
||||
{
|
||||
const labelList& pFaces = mesh.pointFaces()[meshPointI];
|
||||
|
||||
forAll(pFaces, pFaceI)
|
||||
{
|
||||
affectedFaces.insert(pFaces[pFaceI]);
|
||||
}
|
||||
}
|
||||
}
|
||||
forAll(pp1, i)
|
||||
{
|
||||
affectedFaces.erase(pp1.start() + i);
|
||||
}
|
||||
// Remove patch0 from renumbered faces. Should not be nessecary since
|
||||
// patch0 and 1 should not share any point (if created by mergeMeshing)
|
||||
// so affectedFaces should not contain any patch0 faces but you can
|
||||
// never be sure what the user is doing.
|
||||
forAll(pp0, i)
|
||||
{
|
||||
if (affectedFaces.erase(pp0.start() + i))
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"perfectInterface::setRefinement(polyTopoChange&) const"
|
||||
) << "Found face " << pp0.start() + i << " vertices "
|
||||
<< mesh.faces()[pp0.start() + i] << " whose points are"
|
||||
<< " used both by master patch " << pp0.name()
|
||||
<< " and slave patch " << pp1.name()
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 2. Renumber (non patch0/1) faces.
|
||||
for
|
||||
labelList pp1Labels(identity(patch1.size())+patch1.start());
|
||||
indirectPrimitivePatch pp1
|
||||
(
|
||||
labelHashSet::const_iterator iter = affectedFaces.begin();
|
||||
iter != affectedFaces.end();
|
||||
++iter
|
||||
)
|
||||
{
|
||||
label faceI = iter.key();
|
||||
IndirectList<face>(mesh.faces(), pp1Labels),
|
||||
mesh.points()
|
||||
);
|
||||
|
||||
const face& f = mesh.faces()[faceI];
|
||||
|
||||
face newFace(f.size());
|
||||
|
||||
forAll(newFace, fp)
|
||||
{
|
||||
newFace[fp] = renumberPoints[f[fp]];
|
||||
}
|
||||
|
||||
label nbr = -1;
|
||||
|
||||
label patchI = -1;
|
||||
|
||||
if (mesh.isInternalFace(faceI))
|
||||
{
|
||||
nbr = mesh.faceNeighbour()[faceI];
|
||||
}
|
||||
else
|
||||
{
|
||||
patchI = patches.whichPatch(faceI);
|
||||
}
|
||||
|
||||
label zoneID = mesh.faceZones().whichZone(faceI);
|
||||
|
||||
bool zoneFlip = false;
|
||||
|
||||
if (zoneID >= 0)
|
||||
{
|
||||
const faceZone& fZone = mesh.faceZones()[zoneID];
|
||||
|
||||
zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
|
||||
}
|
||||
|
||||
ref.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
newFace, // modified face
|
||||
faceI, // label of face being modified
|
||||
mesh.faceOwner()[faceI], // owner
|
||||
nbr, // neighbour
|
||||
false, // face flip
|
||||
patchI, // patch for face
|
||||
false, // remove from zone
|
||||
zoneID, // zone for face
|
||||
zoneFlip // face flip in zone
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// 3. Remove patch1 points
|
||||
forAll(meshPts1, i)
|
||||
{
|
||||
label meshPointI = meshPts1[i];
|
||||
|
||||
if (meshPointI != renumberPoints[meshPointI])
|
||||
{
|
||||
ref.setAction(polyRemovePoint(meshPointI));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 4. Remove patch1 faces
|
||||
forAll(pp1, i)
|
||||
{
|
||||
ref.setAction(polyRemoveFace(pp1.start() + i));
|
||||
}
|
||||
|
||||
|
||||
// 5. Modify patch0 faces for new points (not really nessecary; see
|
||||
// comment above about patch1 and patch0 never sharing points) and
|
||||
// becoming internal.
|
||||
const boolList& mfFlip =
|
||||
mesh.faceZones()[faceZoneID_.index()].flipMap();
|
||||
|
||||
forAll(pp0, i)
|
||||
{
|
||||
label faceI = pp0.start() + i;
|
||||
|
||||
const face& f = mesh.faces()[faceI];
|
||||
|
||||
face newFace(f.size());
|
||||
|
||||
forAll(newFace, fp)
|
||||
{
|
||||
newFace[fp] = renumberPoints[f[fp]];
|
||||
}
|
||||
|
||||
label own = mesh.faceOwner()[faceI];
|
||||
|
||||
label pp1FaceI = pp1.start() + from0To1Faces[i];
|
||||
|
||||
label nbr = mesh.faceOwner()[pp1FaceI];
|
||||
|
||||
if (own < nbr)
|
||||
{
|
||||
ref.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
newFace, // modified face
|
||||
faceI, // label of face being modified
|
||||
own, // owner
|
||||
nbr, // neighbour
|
||||
false, // face flip
|
||||
-1, // patch for face
|
||||
false, // remove from zone
|
||||
faceZoneID_.index(), // zone for face
|
||||
mfFlip[i] // face flip in zone
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
ref.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
newFace.reverseFace(), // modified face
|
||||
faceI, // label of face being modified
|
||||
nbr, // owner
|
||||
own, // neighbour
|
||||
false, // face flip
|
||||
-1, // patch for face
|
||||
false, // remove from zone
|
||||
faceZoneID_.index(), // zone for face
|
||||
!mfFlip[i] // face flip in zone
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
setRefinement(pp0, pp1, ref);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user