diff --git a/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.C b/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.C index 3bcd500d04cdab78995873cd180db3b7d9508448..e1328495980191aa44fba0f6512325245659d686 100644 --- a/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.C +++ b/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.C @@ -34,15 +34,16 @@ const Foam::label Foam::globalIndexAndTransform::base_ = 32; // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -bool Foam::globalIndexAndTransform::matchTransform +Foam::label Foam::globalIndexAndTransform::matchTransform ( const List<vectorTensorTransform>& refTransforms, + label& matchedRefTransformI, const vectorTensorTransform& testTransform, scalar tolerance, - bool bothSigns + bool checkBothSigns ) const { - // return min(mag(transforms_ - sepVec)) > tol + matchedRefTransformI = -1; forAll(refTransforms, i) { @@ -82,10 +83,12 @@ bool Foam::globalIndexAndTransform::matchTransform if (vectorDiff < 1 && tensorDiff < 1) { - return true; + matchedRefTransformI = i; + + return +1; } - if (bothSigns) + if (checkBothSigns) { // Test the inverse transform differences too @@ -106,12 +109,14 @@ bool Foam::globalIndexAndTransform::matchTransform 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 dummyMatch = -1; + forAll(patches, patchI) { const polyPatch& pp = patches[patchI]; @@ -145,7 +152,17 @@ void Foam::globalIndexAndTransform::determineTransforms() vectorTensorTransform transform(sepVec); - if (!matchTransform(transforms_, transform, tol, false)) + if + ( + matchTransform + ( + transforms_, + dummyMatch, + transform, + tol, + false + ) == 0 + ) { transforms_[nextTrans++] = transform; } @@ -166,7 +183,7 @@ void Foam::globalIndexAndTransform::determineTransforms() } else if (!cpp.parallel()) { - const tensorField& transTensors = cpp.forwardT(); + const tensorField& transTensors = cpp.reverseT(); forAll(transTensors, tTI) { @@ -178,7 +195,17 @@ void Foam::globalIndexAndTransform::determineTransforms() vectorTensorTransform transform(transT); - if (!matchTransform(transforms_, transform, tol, false)) + if + ( + matchTransform + ( + transforms_, + dummyMatch, + transform, + tol, + false + ) == 0 + ) { transforms_[nextTrans++] = transform; } @@ -225,7 +252,17 @@ void Foam::globalIndexAndTransform::determineTransforms() { scalar tol = coupledPolyPatch::matchTol; - if (!matchTransform(transforms_, transform, tol, true)) + if + ( + matchTransform + ( + transforms_, + dummyMatch, + transform, + tol, + true + ) == 0 + ) { 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 * * * * * * * * * * * * * * // Foam::globalIndexAndTransform::globalIndexAndTransform @@ -297,11 +451,16 @@ Foam::globalIndexAndTransform::globalIndexAndTransform const polyMesh& mesh ) : - mesh_(mesh) + mesh_(mesh), + transforms_(), + transformPermutations_(), + patchTransformSign_() { determineTransforms(); determineTransformPermutations(); + + determinePatchTransformSign(); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // diff --git a/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.H b/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.H index 4983fb4c16ea9c2847de07eaa5441cecdf4b1b7e..cba4bc59eb76cd2101c93fedc358c4c00c2e3509 100644 --- a/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.H +++ b/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.H @@ -82,6 +82,11 @@ class globalIndexAndTransform // transform. 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 @@ -97,13 +102,20 @@ class globalIndexAndTransform //- Generate all of the transformation permutations void determineTransformPermutations(); - //- Test a list of reference transforms to see if the test transform - bool matchTransform + //- Determine which patch uses which transform (if any) and which + //- 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, + label& matchedRefTransformI, const vectorTensorTransform& testTransform, scalar tolerance, - bool bothSigns + bool checkBothSigns ) const; //- Disallow default bitwise copy construct @@ -171,12 +183,33 @@ public: inline const List<vectorTensorTransform>& transformPermutations() const; + //- Return access to the per-patch transform-sign pairs + inline const List<Pair<label> >& patchTransformSign() const; + //- Access the overall (permuted) transform corresponding // to the transformIndex inline const vectorTensorTransform& transform ( label transformIndex ) 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; + }; diff --git a/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransformI.H b/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransformI.H index fe2a6034a7ca94db4126b52ddbb0c8c01b399d4b..f2928899f255c1aa809f8298e9021d47f4b51fed 100644 --- a/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransformI.H +++ b/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransformI.H @@ -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 ( 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; +} + + // ************************************************************************* //