ENH: Access to patch transform permutations.

This commit is contained in:
graham
2010-10-01 14:23:01 +01:00
parent 68f13d6d8a
commit b46764344e
3 changed files with 424 additions and 15 deletions

View File

@ -34,15 +34,16 @@ const Foam::label Foam::globalIndexAndTransform::base_ = 32;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::globalIndexAndTransform::matchTransform Foam::label Foam::globalIndexAndTransform::matchTransform
( (
const List<vectorTensorTransform>& refTransforms, const List<vectorTensorTransform>& refTransforms,
label& matchedRefTransformI,
const vectorTensorTransform& testTransform, const vectorTensorTransform& testTransform,
scalar tolerance, scalar tolerance,
bool bothSigns bool checkBothSigns
) const ) const
{ {
// return min(mag(transforms_ - sepVec)) > tol matchedRefTransformI = -1;
forAll(refTransforms, i) forAll(refTransforms, i)
{ {
@ -82,10 +83,12 @@ bool Foam::globalIndexAndTransform::matchTransform
if (vectorDiff < 1 && tensorDiff < 1) if (vectorDiff < 1 && tensorDiff < 1)
{ {
return true; matchedRefTransformI = i;
return +1;
} }
if (bothSigns) if (checkBothSigns)
{ {
// Test the inverse transform differences too // Test the inverse transform differences too
@ -106,12 +109,14 @@ bool Foam::globalIndexAndTransform::matchTransform
if (vectorDiff < 1 && tensorDiff < 1) if (vectorDiff < 1 && tensorDiff < 1)
{ {
return true; matchedRefTransformI = i;
return -1;
} }
} }
} }
return false; return 0;
} }
@ -123,6 +128,8 @@ void Foam::globalIndexAndTransform::determineTransforms()
label nextTrans = 0; label nextTrans = 0;
label dummyMatch = -1;
forAll(patches, patchI) forAll(patches, patchI)
{ {
const polyPatch& pp = patches[patchI]; const polyPatch& pp = patches[patchI];
@ -145,7 +152,17 @@ void Foam::globalIndexAndTransform::determineTransforms()
vectorTensorTransform transform(sepVec); vectorTensorTransform transform(sepVec);
if (!matchTransform(transforms_, transform, tol, false)) if
(
matchTransform
(
transforms_,
dummyMatch,
transform,
tol,
false
) == 0
)
{ {
transforms_[nextTrans++] = transform; transforms_[nextTrans++] = transform;
} }
@ -166,7 +183,7 @@ void Foam::globalIndexAndTransform::determineTransforms()
} }
else if (!cpp.parallel()) else if (!cpp.parallel())
{ {
const tensorField& transTensors = cpp.forwardT(); const tensorField& transTensors = cpp.reverseT();
forAll(transTensors, tTI) forAll(transTensors, tTI)
{ {
@ -178,7 +195,17 @@ void Foam::globalIndexAndTransform::determineTransforms()
vectorTensorTransform transform(transT); vectorTensorTransform transform(transT);
if (!matchTransform(transforms_, transform, tol, false)) if
(
matchTransform
(
transforms_,
dummyMatch,
transform,
tol,
false
) == 0
)
{ {
transforms_[nextTrans++] = transform; transforms_[nextTrans++] = transform;
} }
@ -225,7 +252,17 @@ void Foam::globalIndexAndTransform::determineTransforms()
{ {
scalar tol = coupledPolyPatch::matchTol; scalar tol = coupledPolyPatch::matchTol;
if (!matchTransform(transforms_, transform, tol, true)) if
(
matchTransform
(
transforms_,
dummyMatch,
transform,
tol,
true
) == 0
)
{ {
transforms_[nextTrans++] = transform; transforms_[nextTrans++] = transform;
} }
@ -290,6 +327,123 @@ void Foam::globalIndexAndTransform::determineTransformPermutations()
} }
void Foam::globalIndexAndTransform::determinePatchTransformSign()
{
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
patchTransformSign_.setSize(patches.size(), Pair<label>(-1, 0));
label matchTransI = -1;
forAll(patches, patchI)
{
const polyPatch& pp = patches[patchI];
// Pout<< nl << patchI << " " << pp.name() << endl;
if (isA<coupledPolyPatch>(pp))
{
const coupledPolyPatch& cpp =
refCast<const coupledPolyPatch>(pp);
if (cpp.separated())
{
const vectorField& sepVecs = cpp.separation();
// Pout<< "sepVecs " << sepVecs << endl;
// This loop is implicitly expecting only a single
// value for separation()
forAll(sepVecs, sVI)
{
const vector& sepVec = sepVecs[sVI];
if (mag(sepVec) > SMALL)
{
scalar tol = coupledPolyPatch::matchTol;
vectorTensorTransform t(sepVec);
label sign = matchTransform
(
transforms_,
matchTransI,
t,
tol,
true
);
// Pout<< sign << " " << matchTransI << endl;
// List<label> permutation(transforms_.size(), 0);
// permutation[matchTransI] = sign;
// Pout<< encodeTransformIndex(permutation) << nl
// << transformPermutations_
// [
// encodeTransformIndex(permutation)
// ]
// << endl;
patchTransformSign_[patchI] =
Pair<label>(matchTransI, sign);
}
}
}
else if (!cpp.parallel())
{
const tensorField& transTensors = cpp.reverseT();
// Pout<< "transTensors " << transTensors << endl;
// This loop is implicitly expecting only a single
// value for reverseT()
forAll(transTensors, tTI)
{
const tensor& transT = transTensors[tTI];
if (mag(transT - I) > SMALL)
{
scalar tol = coupledPolyPatch::matchTol;
vectorTensorTransform t(transT);
label sign = matchTransform
(
transforms_,
matchTransI,
t,
tol,
true
);
// Pout<< sign << " " << matchTransI << endl;
// List<label> permutation(transforms_.size(), 0);
// permutation[matchTransI] = sign;
// Pout<< encodeTransformIndex(permutation) << nl
// << transformPermutations_
// [
// encodeTransformIndex(permutation)
// ]
// << endl;
patchTransformSign_[patchI] =
Pair<label>(matchTransI, sign);
}
}
}
}
}
// Pout<< patchTransformSign_ << endl;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::globalIndexAndTransform::globalIndexAndTransform Foam::globalIndexAndTransform::globalIndexAndTransform
@ -297,11 +451,16 @@ Foam::globalIndexAndTransform::globalIndexAndTransform
const polyMesh& mesh const polyMesh& mesh
) )
: :
mesh_(mesh) mesh_(mesh),
transforms_(),
transformPermutations_(),
patchTransformSign_()
{ {
determineTransforms(); determineTransforms();
determineTransformPermutations(); determineTransformPermutations();
determinePatchTransformSign();
} }
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //

View File

@ -82,6 +82,11 @@ class globalIndexAndTransform
// transform. // transform.
List<vectorTensorTransform> transformPermutations_; List<vectorTensorTransform> transformPermutations_;
//- Mapping from patch index to which transform it matches (or
// -1 for none) (.first()) and what sign to us for it,
// i.e. +/- 1 (.second()).
List<Pair<label> > patchTransformSign_;
// Private static data // Private static data
@ -97,13 +102,20 @@ class globalIndexAndTransform
//- Generate all of the transformation permutations //- Generate all of the transformation permutations
void determineTransformPermutations(); void determineTransformPermutations();
//- Test a list of reference transforms to see if the test transform //- Determine which patch uses which transform (if any) and which
bool matchTransform //- sign to use
void determinePatchTransformSign();
//- Test a list of reference transforms to see if the test
// transform matches one. Return +1 or -1 depending on the
// sign of the match, or 0 if none matches.
label matchTransform
( (
const List<vectorTensorTransform>& refTransforms, const List<vectorTensorTransform>& refTransforms,
label& matchedRefTransformI,
const vectorTensorTransform& testTransform, const vectorTensorTransform& testTransform,
scalar tolerance, scalar tolerance,
bool bothSigns bool checkBothSigns
) const; ) const;
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
@ -171,12 +183,33 @@ public:
inline const List<vectorTensorTransform>& inline const List<vectorTensorTransform>&
transformPermutations() const; transformPermutations() const;
//- Return access to the per-patch transform-sign pairs
const List<Pair<label> >& patchTransformSign() const;
//- Access the overall (permuted) transform corresponding //- Access the overall (permuted) transform corresponding
// to the transformIndex // to the transformIndex
inline const vectorTensorTransform& transform inline const vectorTensorTransform& transform
( (
label transformIndex label transformIndex
) const; ) const;
//- Access the all of the indices of the transform
// permutations corresponding the transforms of the
// listed patch indices
inline labelList transformIndicesForPatches
(
const labelHashSet& patchIs
) const;
//- Apply all of the transform permutations
// corresponding the transforms of the listed patch
// indices to the supplied point
inline pointField transformPatches
(
const labelHashSet& patchIs,
const point& pt
) const;
}; };

View File

@ -180,6 +180,13 @@ Foam::globalIndexAndTransform::transformPermutations() const
} }
const Foam::List<Foam::Pair<Foam::label> >&
Foam::globalIndexAndTransform::patchTransformSign() const
{
return patchTransformSign_;
}
const Foam::vectorTensorTransform& Foam::globalIndexAndTransform::transform const Foam::vectorTensorTransform& Foam::globalIndexAndTransform::transform
( (
label transformIndex label transformIndex
@ -189,4 +196,214 @@ const Foam::vectorTensorTransform& Foam::globalIndexAndTransform::transform
} }
Foam::labelList Foam::globalIndexAndTransform::transformIndicesForPatches
(
const labelHashSet& patchIs
) const
{
List<label> permutation(transforms_.size(), 0);
labelList selectedTransformIs(0);
if (patchIs.empty() || transforms_.empty())
{
return selectedTransformIs;
}
forAllConstIter(labelHashSet, patchIs, iter)
{
label patchI = iter.key();
const Pair<label>& transSign = patchTransformSign_[patchI];
label matchTransI = transSign.first();
if (matchTransI > -1)
{
label sign = transSign.second();
// If this transform been found already by a patch?
if (permutation[matchTransI] != 0)
{
// If so, if they have opposite signs, then this is
// considered an error. They are allowed to be the
// same sign, but this only results in a single
// transform.
if (permutation[matchTransI] != sign)
{
FatalErrorIn
(
"const Foam::List<Foam::vectorTensorTransform>& "
"Foam::globalIndexAndTransform::transformsForPatches"
"("
"const labelList& patchIs"
") const"
)
<< "More than one patch accessing the same transform "
<< "but not of the same sign."
<< exit(FatalError);
}
}
else
{
permutation[matchTransI] = sign;
}
}
}
label nUsedTrans = sum(mag(permutation));
if (nUsedTrans == 0)
{
return selectedTransformIs;
}
// Number of selected transformations
label nSelTrans = pow(2, nUsedTrans) - 1;
// Pout<< nl << permutation << nl << endl;
selectedTransformIs.setSize(nSelTrans);
switch (nUsedTrans)
{
case 1:
{
selectedTransformIs[0] = encodeTransformIndex(permutation);
break;
}
case 2:
{
List<label> tempPermutation = permutation;
label a = 0;
label b = 1;
// When there are two selected transforms out of three, we
// need to choose which of them are being permuted
if (transforms_.size() > nUsedTrans)
{
if (permutation[0] == 0)
{
a = 1;
b = 2;
}
else if (permutation[1] == 0)
{
a = 0;
b = 2;
}
else if (permutation[2] == 0)
{
a = 0;
b = 1;
}
}
tempPermutation[a] = a;
tempPermutation[b] = permutation[b];
selectedTransformIs[0] = encodeTransformIndex(tempPermutation);
tempPermutation[a] = permutation[a];
tempPermutation[b] = a;
selectedTransformIs[1] = encodeTransformIndex(tempPermutation);
tempPermutation[a] = permutation[a];
tempPermutation[b] = permutation[b];
selectedTransformIs[2] = encodeTransformIndex(tempPermutation);
break;
}
case 3:
{
List<label> tempPermutation = permutation;
tempPermutation[0] = 0;
tempPermutation[1] = 0;
tempPermutation[2] = permutation[2];
selectedTransformIs[0] = encodeTransformIndex(tempPermutation);
tempPermutation[0] = 0;
tempPermutation[1] = permutation[1];
tempPermutation[2] = 0;
selectedTransformIs[1] = encodeTransformIndex(tempPermutation);
tempPermutation[0] = 0;
tempPermutation[1] = permutation[1];
tempPermutation[2] = permutation[2];
selectedTransformIs[2] = encodeTransformIndex(tempPermutation);
tempPermutation[0] = permutation[0];
tempPermutation[1] = 0;
tempPermutation[2] = 0;
selectedTransformIs[3] = encodeTransformIndex(tempPermutation);
tempPermutation[0] = permutation[0];
tempPermutation[1] = 0;
tempPermutation[2] = permutation[2];
selectedTransformIs[4] = encodeTransformIndex(tempPermutation);
tempPermutation[0] = permutation[0];
tempPermutation[1] = permutation[1];
tempPermutation[2] = 0;
selectedTransformIs[5] = encodeTransformIndex(tempPermutation);
tempPermutation[0] = permutation[0];
tempPermutation[1] = permutation[1];
tempPermutation[2] = permutation[2];
selectedTransformIs[6] = encodeTransformIndex(tempPermutation);
break;
}
default:
{
FatalErrorIn
(
"const Foam::List<Foam::vectorTensorTransform>& "
"Foam::globalIndexAndTransform::transformsForPatches"
"("
"const labelList& patchIs"
") const"
)
<< "Only 1-3 transforms are possible."
<< exit(FatalError);
}
}
return selectedTransformIs;
}
Foam::pointField Foam::globalIndexAndTransform::transformPatches
(
const labelHashSet& patchIs,
const point& pt
) const
{
labelList transIs = transformIndicesForPatches(patchIs);
// Pout<< patchIs << nl << transIs << endl;
pointField transPts(transIs.size());
forAll(transIs, tII)
{
transPts[tII] = transformPermutations_[transIs[tII]].transform(pt);
}
return transPts;
}
// ************************************************************************* // // ************************************************************************* //