diff --git a/src/AMIInterpolation/AMIInterpolation.C b/src/AMIInterpolation/AMIInterpolation.C index 7e9c15caa74029db82552164767dd5f4d2de562b..9bc928d69a71e26d3e45ce3d0918367ad264dab6 100644 --- a/src/AMIInterpolation/AMIInterpolation.C +++ b/src/AMIInterpolation/AMIInterpolation.C @@ -28,7 +28,6 @@ License #include "indexedOctree.H" #include "meshTools.H" #include "mergePoints.H" -#include "globalIndex.H" #include "vtkSurfaceWriter.H" @@ -156,8 +155,10 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::distributePatches ( const mapDistribute& map, const primitivePatch& pp, + const globalIndex& gi, List<faceList>& faces, - List<pointField>& points + List<pointField>& points, + List<labelList>& faceIDs ) { PstreamBuffers pBufs(Pstream::nonBlocking); @@ -168,6 +169,12 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::distributePatches if (domain != Pstream::myProcNo() && sendElems.size()) { + labelList globalElems(sendElems.size()); + forAll(sendElems, i) + { + globalElems[i] = gi.toGlobal(sendElems[i]); + } + faceList subFaces(UIndirectList<face>(pp, sendElems)); primitivePatch subPatch ( @@ -182,7 +189,9 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::distributePatches } UOPstream toDomain(domain, pBufs); - toDomain << subPatch.localFaces() << subPatch.localPoints(); + toDomain + << subPatch.localFaces() << subPatch.localPoints() + << globalElems; } } @@ -191,6 +200,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::distributePatches faces.setSize(Pstream::nProcs()); points.setSize(Pstream::nProcs()); + faceIDs.setSize(Pstream::nProcs()); { // Set up 'send' to myself @@ -211,6 +221,12 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::distributePatches faces[Pstream::myProcNo()] = subPatch.localFaces(); points[Pstream::myProcNo()] = subPatch.localPoints(); + + faceIDs[Pstream::myProcNo()].setSize(sendElems.size()); + forAll(sendElems, i) + { + faceIDs[Pstream::myProcNo()][i] = gi.toGlobal(sendElems[i]); + } } // Consume @@ -221,7 +237,10 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::distributePatches if (domain != Pstream::myProcNo() && recvElems.size()) { UIPstream str(domain, pBufs); - str >> faces[domain] >> points[domain]; + + str >> faces[domain] + >> points[domain] + >> faceIDs[domain]; } } } @@ -233,14 +252,17 @@ distributeAndMergePatches ( const mapDistribute& map, const primitivePatch& tgtPatch, + const globalIndex& gi, faceList& tgtFaces, - pointField& tgtPoints + pointField& tgtPoints, + labelList& tgtFaceIDs ) { // Exchange per-processor data List<faceList> allFaces; List<pointField> allPoints; - distributePatches(map, tgtPatch, allFaces, allPoints); + List<labelList> allTgtFaceIDs; + distributePatches(map, tgtPatch, gi, allFaces, allPoints, allTgtFaceIDs); // Renumber and flatten label nFaces = 0; @@ -250,13 +272,21 @@ distributeAndMergePatches nFaces += allFaces[procI].size(); nPoints += allPoints[procI].size(); } + tgtFaces.setSize(nFaces); - nFaces = 0; tgtPoints.setSize(nPoints); + +//reduce(nFaces, sumOp<label>()); + tgtFaceIDs.setSize(nFaces); + + nFaces = 0; nPoints = 0; // My own data first { + const labelList& faceIDs = allTgtFaceIDs[Pstream::myProcNo()]; + SubList<label>(tgtFaceIDs, faceIDs.size()).assign(faceIDs); + const faceList& fcs = allFaces[Pstream::myProcNo()]; forAll(fcs, i) { @@ -268,6 +298,7 @@ distributeAndMergePatches newF[fp] = f[fp] + nPoints; } } + const pointField& pts = allPoints[Pstream::myProcNo()]; forAll(pts, i) { @@ -275,11 +306,15 @@ distributeAndMergePatches } } - // Other proc data first + + // Other proc data follows forAll(allFaces, procI) { if (procI != Pstream::myProcNo()) { + const labelList& faceIDs = allTgtFaceIDs[procI]; + SubList<label>(tgtFaceIDs, faceIDs.size(), nFaces).assign(faceIDs); + const faceList& fcs = allFaces[procI]; forAll(fcs, i) { @@ -291,6 +326,7 @@ distributeAndMergePatches newF[fp] = f[fp] + nPoints; } } + const pointField& pts = allPoints[procI]; forAll(pts, i) { @@ -977,27 +1013,6 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcAddressing << endl; } - // normalise weights by face areas - forAll(srcAddr, faceI) - { - const DynamicList<label>& addressing = srcAddr[faceI]; - forAll(addressing, addrI) - { - const scalar faceArea = srcPatch0[faceI].mag(srcPoints); - srcWght[faceI][addrI] /= faceArea; - } - } - - forAll(tgtAddr, faceI) - { - const DynamicList<label>& addressing = tgtAddr[faceI]; - forAll(addressing, addrI) - { - const scalar faceArea = tgtPatch0[faceI].mag(tgtPoints); - tgtWght[faceI][addrI] /= faceArea; - } - } - // transfer data to persistent storage srcAddress_.setSize(srcPatch.size()); srcWeights_.setSize(srcPatch.size()); @@ -1017,11 +1032,11 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcAddressing } - template<class SourcePatch, class TargetPatch> void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights ( - const word& patchType, + const primitivePatch& patch, + const word& patchName, const labelListList& addr, scalarListList& wght, const bool output @@ -1029,11 +1044,26 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights { scalarList wghtSum(wght.size(), 0.0); + scalar minBound = VGREAT; + scalar maxBound = -VGREAT; + // Normalise the weights forAll(wght, faceI) { scalar s = sum(wght[faceI]); wghtSum[faceI] = s; + + scalar t = 1; // s/patch[faceI].mag(patch.localPoints()); + + if (t < minBound) + { + minBound = t; + } + + if (t > maxBound) + { + maxBound = t; + } forAll(addr[faceI], i) { @@ -1043,8 +1073,9 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights if (output) { - Info<< "AMI: Patch " << patchType << " weights min/max = " - << gMin(wghtSum) << ", " << gMax(wghtSum) << endl; + Info<< "AMI: Patch " << patchName << " weights min/max = " + << returnReduce(minBound, minOp<scalar>()) << ", " + << returnReduce(maxBound, maxOp<scalar>()) << endl; } } @@ -1110,14 +1141,28 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update if (Pstream::parRun()) { - // create processor map of overlapping faces + // convert local addressing to global addressing + globalIndex globalSrcFaces(srcPatch.size()); + globalIndex globalTgtFaces(tgtPatch.size()); + + // Create processor map of overlapping faces. This map gets + // (possibly remote) faces from the tgtPatch such that they together + // cover all of the srcPatch. autoPtr<mapDistribute> mapPtr = calcProcMap(srcPatch, tgtPatch); const mapDistribute& map = mapPtr(); // create new target patch that fully encompasses source patch + + // faces and points faceList newTgtFaces; pointField newTgtPoints; - distributeAndMergePatches(map, tgtPatch, newTgtFaces, newTgtPoints); + // original faces from tgtPatch (in globalIndexing since might be + // remote) + labelList tgtFaceIDs; + distributeAndMergePatches + ( + map, tgtPatch, globalTgtFaces, newTgtFaces, newTgtPoints, tgtFaceIDs + ); primitivePatch newTgtPatch @@ -1130,61 +1175,44 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update newTgtPoints ); -// checkPatches(srcPatch, newTgtPatch); + checkPatches(srcPatch, newTgtPatch); - // calculate AMI interpolation + // calculate AMI interpolation. calcAddressing(srcPatch, newTgtPatch, surf); + // Now + // ~~~ + // srcAddress_ : per srcPatch face a list of the newTgtPatch (not + // tgtPatch) faces it overlaps + // tgtAddress_ : per newTgtPatch (not tgtPatch) face a list of the + // srcPatch faces it overlaps - // convert local addressing to global addressing - globalIndex globalSrcFaces(srcAddress_.size()); - forAll(tgtAddress_, i) + + // Rework newTgtPatch indices into globalIndices of tgtPatch + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + + forAll(srcAddress_, i) { - labelList& addressing = tgtAddress_[i]; + labelList& addressing = srcAddress_[i]; forAll(addressing, addrI) { - addressing[addrI] = globalSrcFaces.toGlobal(addressing[addrI]); + addressing[addrI] = tgtFaceIDs[addressing[addrI]]; } } - globalIndex globalTgtFaces(tgtAddress_.size()); - forAll(srcAddress_, i) + forAll(tgtAddress_, i) { - labelList& addressing = srcAddress_[i]; + labelList& addressing = tgtAddress_[i]; forAll(addressing, addrI) { - addressing[addrI] = globalTgtFaces.toGlobal(addressing[addrI]); + addressing[addrI] = globalSrcFaces.toGlobal(addressing[addrI]); } } - - // send maps -/* - mapDistribute::distribute - ( - Pstream::nonBlocking, - List<labelPair>(), - srcPatch.size(), - map.constructMap(), - map.subMap(), - srcAddress_, - ListPlusEqOp<label>(), - labelList() - ); - - mapDistribute::distribute - ( - Pstream::nonBlocking, - List<labelPair>(), - srcPatch.size(), - map.constructMap(), - map.subMap(), - srcWeights_, - ListPlusEqOp<scalar>(), - scalarList() - ); -*/ + // send data back to originating procs. Note that contributions + // from different processors get added (ListPlusEqOp). mapDistribute::distribute ( @@ -1210,25 +1238,20 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update scalarList() ); - if (debug) - { - writeWeights(srcWeights_, srcPatch, "VTK", "source"); - writeWeights(tgtWeights_, newTgtPatch, "VTK", "target"); - } - - // weights normalisation - normaliseWeights("source", srcAddress_, srcWeights_, true); - normaliseWeights("target", tgtAddress_, tgtWeights_, true); - + normaliseWeights(srcPatch, "source", srcAddress_, srcWeights_, true); + normaliseWeights(tgtPatch, "target", tgtAddress_, tgtWeights_, true); // cache maps and reset addresses List<Map<label> > cMap; srcMapPtr_.reset(new mapDistribute(globalSrcFaces, tgtAddress_, cMap)); tgtMapPtr_.reset(new mapDistribute(globalTgtFaces, srcAddress_, cMap)); + if (debug) { + writeWeights(srcWeights_, srcPatch, "VTK", "source"); + writeWeights(tgtWeights_, tgtPatch, "VTK", "target"); writeFaceConnectivity(srcPatch, newTgtPatch); } } @@ -1244,8 +1267,8 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update writeWeights(tgtWeights_, tgtPatch, "VTK", "target"); } - normaliseWeights("source", srcAddress_, srcWeights_, true); - normaliseWeights("target", tgtAddress_, tgtWeights_, true); + normaliseWeights(srcPatch, "source", srcAddress_, srcWeights_, true); + normaliseWeights(tgtPatch, "target", tgtAddress_, tgtWeights_, true); } patchI++; @@ -1260,13 +1283,13 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource const Field<Type>& fld ) const { - if (fld.size() != tgtAddress_.size()) + if (fld.size() != tgtPatchSize_) { FatalErrorIn ( "AMIInterpolation::interpolateToSource(const Field<Type>) const" ) << "Supplied field size is not equal to target patch size. " - << "Target patch = " << tgtAddress_.size() << ", supplied field = " + << "Target patch = " << tgtPatchSize_ << ", supplied field = " << fld.size() << abort(FatalError); } @@ -1352,7 +1375,6 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget ( new Field<Type> ( -// tgtAddress_.size(), tgtPatchSize_, pTraits<Type>::zero ) diff --git a/src/AMIInterpolation/AMIInterpolation.H b/src/AMIInterpolation/AMIInterpolation.H index 711c8d71a7f27d4933a0344bfa8aee6b3e50a38f..f9d722712412bd69ab17fb339e273f310a26de46 100644 --- a/src/AMIInterpolation/AMIInterpolation.H +++ b/src/AMIInterpolation/AMIInterpolation.H @@ -52,6 +52,7 @@ SourceFiles #include "faceAreaIntersect.H" #include "treeBoundBox.H" #include "treeBoundBoxList.H" +#include "globalIndex.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -182,16 +183,20 @@ class AMIInterpolation ( const mapDistribute& map, const primitivePatch& pp, + const globalIndex& gi, List<faceList>& faces, - List<pointField>& points + List<pointField>& points, + List<labelList>& tgtFaceIDs ); void distributeAndMergePatches ( const mapDistribute& map, const primitivePatch& tgtPatch, + const globalIndex& gi, faceList& tgtFaces, - pointField& tgtPoints + pointField& tgtPoints, + labelList& tgtFaceIDs ); autoPtr<mapDistribute> calcProcMap @@ -271,7 +276,8 @@ class AMIInterpolation // numerical error! void normaliseWeights ( - const word& patchType, + const primitivePatch& patch, + const word& patchName, const labelListList& addr, scalarListList& wght, const bool output