ENH: tetrahedron: move slicing with plane. Removed tetPointRef.H

This commit is contained in:
mattijs
2012-01-16 15:48:15 +00:00
parent 6a6986b4ce
commit e2cc8830d4
22 changed files with 605 additions and 2303 deletions

View File

@ -24,436 +24,27 @@ License
\*---------------------------------------------------------------------------*/
#include "tetOverlapVolume.H"
#include "tetrahedron.H"
#include "tetPoints.H"
#include "polyMesh.H"
#include "OFstream.H"
#include "treeBoundBox.H"
#include "indexedOctree.H"
#include "treeDataCell.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::tetOverlapVolume, 0);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::tetOverlapVolume::tetOverlapVolume()
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::tetOverlapVolume::~tetOverlapVolume()
{}
// * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * * //
Foam::point Foam::tetOverlapVolume::planeIntersection
(
const FixedList<scalar, 4>& d,
const tetPoints& t,
const label negI,
const label posI
)
{
return (d[posI]*t[negI] - d[negI]*t[posI])/(-d[negI]+d[posI]);
}
template <class TetOp>
inline void Foam::tetOverlapVolume::decomposePrism
(
const FixedList<point, 6>& points,
TetOp& op
)
{
op(tetPoints(points[1], points[3], points[2], points[0]));
op(tetPoints(points[1], points[2], points[3], points[4]));
op(tetPoints(points[4], points[2], points[3], points[5]));
}
template <class AboveTetOp, class BelowTetOp>
inline void Foam::tetOverlapVolume::tetSliceWithPlane
(
const tetPoints& tet,
const plane& pl,
AboveTetOp& aboveOp,
BelowTetOp& belowOp
)
{
// Distance to plane
FixedList<scalar, 4> d;
label nPos = 0;
forAll(tet, i)
{
d[i] = ((tet[i]-pl.refPoint()) & pl.normal());
if (d[i] > 0)
{
nPos++;
}
}
if (nPos == 4)
{
aboveOp(tet);
}
else if (nPos == 3)
{
// Sliced into below tet and above prism. Prism gets split into
// two tets.
// Find the below tet
label i0 = -1;
forAll(d, i)
{
if (d[i] <= 0)
{
i0 = i;
break;
}
}
label i1 = d.fcIndex(i0);
label i2 = d.fcIndex(i1);
label i3 = d.fcIndex(i2);
point p01 = planeIntersection(d, tet, i0, i1);
point p02 = planeIntersection(d, tet, i0, i2);
point p03 = planeIntersection(d, tet, i0, i3);
// i0 = tetCell vertex 0: p01,p02,p03 outwards pointing triad
// ,, 1 : ,, inwards pointing triad
// ,, 2 : ,, outwards pointing triad
// ,, 3 : ,, inwards pointing triad
//Pout<< "Split 3pos tet " << tet << " d:" << d << " into" << nl;
if (i0 == 0 || i0 == 2)
{
tetPoints t(tet[i0], p01, p02, p03);
//Pout<< " belowtet:" << t << " around i0:" << i0 << endl;
//checkTet(t, "nPos 3, belowTet i0==0 or 2");
belowOp(t);
// Prism
FixedList<point, 6> p;
p[0] = tet[i1];
p[1] = tet[i3];
p[2] = tet[i2];
p[3] = p01;
p[4] = p03;
p[5] = p02;
//Pout<< " aboveprism:" << p << endl;
decomposePrism(p, aboveOp);
}
else
{
tetPoints t(p01, p02, p03, tet[i0]);
//Pout<< " belowtet:" << t << " around i0:" << i0 << endl;
//checkTet(t, "nPos 3, belowTet i0==1 or 3");
belowOp(t);
// Prism
FixedList<point, 6> p;
p[0] = tet[i3];
p[1] = tet[i1];
p[2] = tet[i2];
p[3] = p03;
p[4] = p01;
p[5] = p02;
//Pout<< " aboveprism:" << p << endl;
decomposePrism(p, aboveOp);
}
}
else if (nPos == 2)
{
// Tet cut into two prisms. Determine the positive one.
label pos0 = -1;
label pos1 = -1;
label neg0 = -1;
label neg1 = -1;
forAll(d, i)
{
if (d[i] > 0)
{
if (pos0 == -1)
{
pos0 = i;
}
else
{
pos1 = i;
}
}
else
{
if (neg0 == -1)
{
neg0 = i;
}
else
{
neg1 = i;
}
}
}
//Pout<< "Split 2pos tet " << tet << " d:" << d
// << " around pos0:" << pos0 << " pos1:" << pos1
// << " neg0:" << neg0 << " neg1:" << neg1 << " into" << nl;
const edge posEdge(pos0, pos1);
if (posEdge == edge(0, 1))
{
point p02 = planeIntersection(d, tet, 0, 2);
point p03 = planeIntersection(d, tet, 0, 3);
point p12 = planeIntersection(d, tet, 1, 2);
point p13 = planeIntersection(d, tet, 1, 3);
// Split the resulting prism
{
FixedList<point, 6> p;
p[0] = tet[0];
p[1] = p02;
p[2] = p03;
p[3] = tet[1];
p[4] = p12;
p[5] = p13;
//Pout<< " 01 aboveprism:" << p << endl;
decomposePrism(p, aboveOp);
}
{
FixedList<point, 6> p;
p[0] = tet[2];
p[1] = p02;
p[2] = p12;
p[3] = tet[3];
p[4] = p03;
p[5] = p13;
//Pout<< " 01 belowprism:" << p << endl;
decomposePrism(p, belowOp);
}
}
else if (posEdge == edge(1, 2))
{
point p01 = planeIntersection(d, tet, 0, 1);
point p13 = planeIntersection(d, tet, 1, 3);
point p02 = planeIntersection(d, tet, 0, 2);
point p23 = planeIntersection(d, tet, 2, 3);
// Split the resulting prism
{
FixedList<point, 6> p;
p[0] = tet[1];
p[1] = p01;
p[2] = p13;
p[3] = tet[2];
p[4] = p02;
p[5] = p23;
//Pout<< " 12 aboveprism:" << p << endl;
decomposePrism(p, aboveOp);
}
{
FixedList<point, 6> p;
p[0] = tet[3];
p[1] = p23;
p[2] = p13;
p[3] = tet[0];
p[4] = p02;
p[5] = p01;
//Pout<< " 12 belowprism:" << p << endl;
decomposePrism(p, belowOp);
}
}
else if (posEdge == edge(2, 0))
{
point p01 = planeIntersection(d, tet, 0, 1);
point p03 = planeIntersection(d, tet, 0, 3);
point p12 = planeIntersection(d, tet, 1, 2);
point p23 = planeIntersection(d, tet, 2, 3);
// Split the resulting prism
{
FixedList<point, 6> p;
p[0] = tet[2];
p[1] = p12;
p[2] = p23;
p[3] = tet[0];
p[4] = p01;
p[5] = p03;
//Pout<< " 20 aboveprism:" << p << endl;
decomposePrism(p, aboveOp);
}
{
FixedList<point, 6> p;
p[0] = tet[1];
p[1] = p12;
p[2] = p01;
p[3] = tet[3];
p[4] = p23;
p[5] = p03;
//Pout<< " 20 belowprism:" << p << endl;
decomposePrism(p, belowOp);
}
}
else if (posEdge == edge(0, 3))
{
point p01 = planeIntersection(d, tet, 0, 1);
point p02 = planeIntersection(d, tet, 0, 2);
point p13 = planeIntersection(d, tet, 1, 3);
point p23 = planeIntersection(d, tet, 2, 3);
// Split the resulting prism
{
FixedList<point, 6> p;
p[0] = tet[3];
p[1] = p23;
p[2] = p13;
p[3] = tet[0];
p[4] = p02;
p[5] = p01;
//Pout<< " 03 aboveprism:" << p << endl;
decomposePrism(p, aboveOp);
}
{
FixedList<point, 6> p;
p[0] = tet[2];
p[1] = p23;
p[2] = p02;
p[3] = tet[1];
p[4] = p13;
p[5] = p01;
//Pout<< " 03 belowprism:" << p << endl;
decomposePrism(p, belowOp);
}
}
else if (posEdge == edge(1, 3))
{
point p01 = planeIntersection(d, tet, 0, 1);
point p12 = planeIntersection(d, tet, 1, 2);
point p03 = planeIntersection(d, tet, 0, 3);
point p23 = planeIntersection(d, tet, 2, 3);
// Split the resulting prism
{
FixedList<point, 6> p;
p[0] = tet[1];
p[1] = p12;
p[2] = p01;
p[3] = tet[3];
p[4] = p23;
p[5] = p03;
//Pout<< " 13 aboveprism:" << p << endl;
decomposePrism(p, aboveOp);
}
{
FixedList<point, 6> p;
p[0] = tet[2];
p[1] = p12;
p[2] = p23;
p[3] = tet[0];
p[4] = p01;
p[5] = p03;
//Pout<< " 13 belowprism:" << p << endl;
decomposePrism(p, belowOp);
}
}
else if (posEdge == edge(2, 3))
{
point p02 = planeIntersection(d, tet, 0, 2);
point p12 = planeIntersection(d, tet, 1, 2);
point p03 = planeIntersection(d, tet, 0, 3);
point p13 = planeIntersection(d, tet, 1, 3);
// Split the resulting prism
{
FixedList<point, 6> p;
p[0] = tet[2];
p[1] = p02;
p[2] = p12;
p[3] = tet[3];
p[4] = p03;
p[5] = p13;
//Pout<< " 23 aboveprism:" << p << endl;
decomposePrism(p, aboveOp);
}
{
FixedList<point, 6> p;
p[0] = tet[0];
p[1] = p02;
p[2] = p03;
p[3] = tet[1];
p[4] = p12;
p[5] = p13;
//Pout<< " 23 belowprism:" << p << endl;
decomposePrism(p, belowOp);
}
}
else
{
FatalErrorIn("tetSliceWithPlane(..)") << "Missed edge:" << posEdge
<< abort(FatalError);
}
}
else if (nPos == 1)
{
// Find the positive tet
label i0 = -1;
forAll(d, i)
{
if (d[i] > 0)
{
i0 = i;
break;
}
}
label i1 = d.fcIndex(i0);
label i2 = d.fcIndex(i1);
label i3 = d.fcIndex(i2);
point p01 = planeIntersection(d, tet, i0, i1);
point p02 = planeIntersection(d, tet, i0, i2);
point p03 = planeIntersection(d, tet, i0, i3);
//Pout<< "Split 1pos tet " << tet << " d:" << d << " into" << nl;
if (i0 == 0 || i0 == 2)
{
tetPoints t(tet[i0], p01, p02, p03);
//Pout<< " abovetet:" << t << " around i0:" << i0 << endl;
//checkTet(t, "nPos 1, aboveTets i0==0 or 2");
aboveOp(t);
// Prism
FixedList<point, 6> p;
p[0] = tet[i1];
p[1] = tet[i3];
p[2] = tet[i2];
p[3] = p01;
p[4] = p03;
p[5] = p02;
//Pout<< " belowprism:" << p << endl;
decomposePrism(p, belowOp);
}
else
{
tetPoints t(p01, p02, p03, tet[i0]);
//Pout<< " abovetet:" << t << " around i0:" << i0 << endl;
//checkTet(t, "nPos 1, aboveTets i0==1 or 3");
aboveOp(t);
// Prism
FixedList<point, 6> p;
p[0] = tet[i3];
p[1] = tet[i1];
p[2] = tet[i2];
p[3] = p03;
p[4] = p01;
p[5] = p02;
//Pout<< " belowprism:" << p << endl;
decomposePrism(p, belowOp);
}
}
else // nPos == 0
{
belowOp(tet);
}
}
void Foam::tetOverlapVolume::tetTetOverlap
(
const tetPoints& tetA,
@ -462,16 +53,15 @@ void Foam::tetOverlapVolume::tetTetOverlap
label& nInside,
FixedList<tetPoints, 200>& outsideTets,
label& nOutside
)
) const
{
// Work storage
FixedList<tetPoints, 200> cutInsideTets;
label nCutInside = 0;
storeTetOp inside(insideTets, nInside);
storeTetOp cutInside(cutInsideTets, nCutInside);
dummyTetOp outside;
tetPointRef::storeOp inside(insideTets, nInside);
tetPointRef::storeOp cutInside(cutInsideTets, nCutInside);
tetPointRef::dummyOp outside;
// Cut tetA with all inwards pointing faces of tetB. Any tets remaining
@ -484,7 +74,7 @@ void Foam::tetOverlapVolume::tetTetOverlap
// Cut and insert subtets into cutInsideTets (either by getting
// an index from freeSlots or by appending to insideTets) or
// insert into outsideTets
tetSliceWithPlane(tetA, pl0, cutInside, outside);
tetA.tet().sliceWithPlane(pl0, cutInside, outside);
}
if (nCutInside == 0)
@ -501,7 +91,7 @@ void Foam::tetOverlapVolume::tetTetOverlap
for (label i = 0; i < nCutInside; i++)
{
tetSliceWithPlane(cutInsideTets[i], pl1, inside, outside);
cutInsideTets[i].tet().sliceWithPlane(pl1, inside, outside);
}
if (nInside == 0)
@ -518,7 +108,7 @@ void Foam::tetOverlapVolume::tetTetOverlap
for (label i = 0; i < nInside; i++)
{
tetSliceWithPlane(insideTets[i], pl2, cutInside, outside);
insideTets[i].tet().sliceWithPlane(pl2, cutInside, outside);
}
if (nCutInside == 0)
@ -536,28 +126,27 @@ void Foam::tetOverlapVolume::tetTetOverlap
for (label i = 0; i < nCutInside; i++)
{
tetSliceWithPlane(cutInsideTets[i], pl3, inside, outside);
cutInsideTets[i].tet().sliceWithPlane(pl3, inside, outside);
}
}
}
inline Foam::scalar
Foam::tetOverlapVolume::tetTetOverlapVol
Foam::scalar Foam::tetOverlapVolume::tetTetOverlapVol
(
const tetPoints& tetA,
const tetPoints& tetB
)
) const
{
FixedList<tetPoints, 200> insideTets;
label nInside = 0;
FixedList<tetPoints, 200> cutInsideTets;
label nCutInside = 0;
storeTetOp inside(insideTets, nInside);
storeTetOp cutInside(cutInsideTets, nCutInside);
sumTetVolOp volInside;
dummyTetOp outside;
tetPointRef::storeOp inside(insideTets, nInside);
tetPointRef::storeOp cutInside(cutInsideTets, nCutInside);
tetPointRef::sumVolOp volInside;
tetPointRef::dummyOp outside;
// face0
plane pl0(tetB[1], tetB[3], tetB[2]);
@ -605,12 +194,12 @@ Foam::tetOverlapVolume::tetTetOverlapVol
}
inline const Foam::treeBoundBox Foam::tetOverlapVolume::pyrBb
Foam::treeBoundBox Foam::tetOverlapVolume::pyrBb
(
const pointField& points,
const face& f,
const point& fc
)
) const
{
treeBoundBox bb(fc, fc);
forAll(f, fp)
@ -750,8 +339,8 @@ Foam::scalar Foam::tetOverlapVolume::cellCellOverlapVolumeMinDecomp
Foam::labelList Foam::tetOverlapVolume::overlappingCells
(
const fvMesh& fromMesh,
const fvMesh& toMesh,
const polyMesh& fromMesh,
const polyMesh& toMesh,
const label iTo
) const
{
@ -766,30 +355,4 @@ Foam::labelList Foam::tetOverlapVolume::overlappingCells
}
/*
forAll(cellsA, i)
{
label cellAI = cellsA[i];
treeBoundBox bbA
(
pointField(meshA.points(), meshA.cellPoints()[cellAI])
);
scalar v = cellCellOverlapVolumeMinDecomp
(
meshA,
cellAI,
bbA,
meshB,
cellBI,
bbB
);
overlapVol += v;
nOverlapTests++;
}
*/
// ************************************************************************* //