extrudeMesh does extrusion from existing mesh

This commit is contained in:
mattijs
2009-08-21 17:36:27 +01:00
parent 0708fbbba9
commit 65e925f1fe
18 changed files with 870 additions and 429 deletions

View File

@ -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);
}
}