diff --git a/applications/utilities/mesh/manipulation/createPatch/createPatchDict b/applications/utilities/mesh/manipulation/createPatch/createPatchDict index 35e0b869260322ae8281672cb495b1dfdf93e70a..f731f78df975d825fb55384d244234cb00156f37 100644 --- a/applications/utilities/mesh/manipulation/createPatch/createPatchDict +++ b/applications/utilities/mesh/manipulation/createPatch/createPatchDict @@ -20,6 +20,7 @@ FoamFile // - always: order faces on coupled patches such that they are opposite. This // is done for all coupled faces, not just for any patches created. // - optional: synchronise points on coupled patches. +// - always: remove zero-sized (non-coupled) patches (that were not added) // 1. Create cyclic: // - specify where the faces should come from diff --git a/src/OpenFOAM/db/Time/timeSelector.C b/src/OpenFOAM/db/Time/timeSelector.C index 865f3ee9116584243a91bfa8782611b87baf1d44..60b589a347478408fc08fbb026f468da0e6db971 100644 --- a/src/OpenFOAM/db/Time/timeSelector.C +++ b/src/OpenFOAM/db/Time/timeSelector.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -147,7 +147,7 @@ void Foam::timeSelector::addOptions ( "time", "ranges", - "comma-separated time ranges - eg, ':10,20,40-70,1000:'" + "comma-separated time ranges - eg, ':10,20,40:70,1000:'" ); } diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C index 5781ef991181cc4749ed2c3cac0bd59f1e30925f..0b0e3800f7256b49c7e183b44d9ad8799167bcfc 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C @@ -713,7 +713,7 @@ Foam::label Foam::AMIInterpolation<SourcePatch, TargetPatch>::findTargetFace const pointField& srcPts = srcPatch.points(); const face& srcFace = srcPatch[srcFaceI]; - const point& srcPt = srcFace.centre(srcPts); + const point srcPt = srcFace.centre(srcPts); const scalar srcFaceArea = srcMagSf_[srcFaceI]; // pointIndexHit sample = treePtr_->findNearest(srcPt, sqr(0.1*bb.mag())); @@ -782,6 +782,62 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::appendNbrFaces } +template<class SourcePatch, class TargetPatch> +bool Foam::AMIInterpolation<SourcePatch, TargetPatch>::processSourceFace +( + const SourcePatch& srcPatch, + const TargetPatch& tgtPatch, + const label srcFaceI, + const label tgtStartFaceI, + + // list of tgt face neighbour faces + DynamicList<label>& nbrFaces, + // list of faces currently visited for srcFaceI to avoid multiple hits + DynamicList<label>& visitedFaces, + + // temporary storage for addressing and weights + List<DynamicList<label> >& srcAddr, + List<DynamicList<scalar> >& srcWght, + List<DynamicList<label> >& tgtAddr, + List<DynamicList<scalar> >& tgtWght +) +{ + nbrFaces.clear(); + visitedFaces.clear(); + + // append initial target face and neighbours + nbrFaces.append(tgtStartFaceI); + appendNbrFaces(tgtStartFaceI, tgtPatch, visitedFaces, nbrFaces); + + bool faceProcessed = false; + + do + { + // process new target face + label tgtFaceI = nbrFaces.remove(); + visitedFaces.append(tgtFaceI); + scalar area = interArea(srcFaceI, tgtFaceI, srcPatch, tgtPatch); + + // store when intersection area > 0 + if (area > 0) + { + srcAddr[srcFaceI].append(tgtFaceI); + srcWght[srcFaceI].append(area); + + tgtAddr[tgtFaceI].append(srcFaceI); + tgtWght[tgtFaceI].append(area); + + appendNbrFaces(tgtFaceI, tgtPatch, visitedFaces, nbrFaces); + + faceProcessed = true; + } + + } while (nbrFaces.size() > 0); + + return faceProcessed; +} + + template<class SourcePatch, class TargetPatch> void Foam::AMIInterpolation<SourcePatch, TargetPatch>::setNextFaces ( @@ -811,7 +867,8 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::setNextFaces label faceT = visitedFaces[j]; scalar area = interArea(faceS, faceT, srcPatch0, tgtPatch0); - if (area > 0) + // Check that faces have enough overlap for robust walking + if (area/srcMagSf_[srcFaceI] > faceAreaIntersect::tolerance()) { // TODO - throwing area away - re-use in next iteration? @@ -864,7 +921,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::setNextFaces << "target face" << endl; } -// foundNextSeed = false; + foundNextSeed = false; for (label faceI = startSeedI; faceI < mapFlag.size(); faceI++) { if (mapFlag[faceI]) @@ -887,7 +944,8 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::setNextFaces FatalErrorIn ( - "void Foam::cyclicAMIPolyPatch::setNextFaces" + "void Foam::AMIInterpolation<SourcePatch, TargetPatch>::" + "setNextFaces" "(" "label&, " "label&, " @@ -946,6 +1004,25 @@ Foam::scalar Foam::AMIInterpolation<SourcePatch, TargetPatch>::interArea { area = inter.calc(src, tgt, n, triMode_); } + else + { + WarningIn + ( + "void Foam::AMIInterpolation<SourcePatch, TargetPatch>::" + "interArea" + "(" + "const label, " + "const label, " + "const SourcePatch&, " + "const TargetPatch&" + ") const" + ) << "Invalid normal for source face " << srcFaceI + << " points " << UIndirectList<point>(srcPoints, src) + << " target face " << tgtFaceI + << " points " << UIndirectList<point>(tgtPoints, tgt) + << endl; + } + if ((debug > 1) && (area > 0)) { @@ -956,6 +1033,105 @@ Foam::scalar Foam::AMIInterpolation<SourcePatch, TargetPatch>::interArea } +template<class SourcePatch, class TargetPatch> +void Foam::AMIInterpolation<SourcePatch, TargetPatch>:: +restartUncoveredSourceFace +( + const SourcePatch& srcPatch, + const TargetPatch& tgtPatch, + List<DynamicList<label> >& srcAddr, + List<DynamicList<scalar> >& srcWght, + List<DynamicList<label> >& tgtAddr, + List<DynamicList<scalar> >& tgtWght +) +{ + // Collect all src faces with a low weight + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + labelHashSet lowWeightFaces(100); + forAll(srcWght, srcFaceI) + { + scalar s = sum(srcWght[srcFaceI]); + scalar t = s/srcMagSf_[srcFaceI]; + + if (t < 0.5) + { + lowWeightFaces.insert(srcFaceI); + } + } + + Info<< "AMIInterpolation : restarting search on " + << returnReduce(lowWeightFaces.size(), sumOp<label>()) + << " faces since sum of weights < 0.5" << endl; + + if (lowWeightFaces.size() > 0) + { + // Erase all the lowWeight source faces from the target + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + DynamicList<label> okSrcFaces(10); + DynamicList<scalar> okSrcWeights(10); + forAll(tgtAddr, tgtFaceI) + { + okSrcFaces.clear(); + okSrcWeights.clear(); + DynamicList<label>& srcFaces = tgtAddr[tgtFaceI]; + DynamicList<scalar>& srcWeights = tgtWght[tgtFaceI]; + forAll(srcFaces, i) + { + if (!lowWeightFaces.found(srcFaces[i])) + { + okSrcFaces.append(srcFaces[i]); + okSrcWeights.append(srcWeights[i]); + } + } + if (okSrcFaces.size() < srcFaces.size()) + { + srcFaces.transfer(okSrcFaces); + srcWeights.transfer(okSrcWeights); + } + } + + + + // Restart search from best hit + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + // list of tgt face neighbour faces + DynamicList<label> nbrFaces(10); + + // list of faces currently visited for srcFaceI to avoid multiple hits + DynamicList<label> visitedFaces(10); + + forAllConstIter(labelHashSet, lowWeightFaces, iter) + { + label srcFaceI = iter.key(); + label tgtFaceI = findTargetFace(srcFaceI, srcPatch); + if (tgtFaceI != -1) + { + //bool faceProcessed = + processSourceFace + ( + srcPatch, + tgtPatch, + srcFaceI, + tgtFaceI, + + nbrFaces, + visitedFaces, + + srcAddr, + srcWght, + tgtAddr, + tgtWght + ); + // ? Check faceProcessed to see if restarting has worked. + } + } + } +} + + template<class SourcePatch, class TargetPatch> void Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcAddressing ( @@ -1073,37 +1249,22 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcAddressing DynamicList<label> nonOverlapFaces; do { - nbrFaces.clear(); - visitedFaces.clear(); - - // append initial target face and neighbours - nbrFaces.append(tgtFaceI); - appendNbrFaces(tgtFaceI, tgtPatch, visitedFaces, nbrFaces); - - bool faceProcessed = false; - - do - { - // process new target face - tgtFaceI = nbrFaces.remove(); - visitedFaces.append(tgtFaceI); - scalar area = interArea(srcFaceI, tgtFaceI, srcPatch, tgtPatch); - - // store when intersection area > 0 - if (area > 0) - { - srcAddr[srcFaceI].append(tgtFaceI); - srcWght[srcFaceI].append(area); - - tgtAddr[tgtFaceI].append(srcFaceI); - tgtWght[tgtFaceI].append(area); - - appendNbrFaces(tgtFaceI, tgtPatch, visitedFaces, nbrFaces); + // Do advancing front starting from srcFaceI,tgtFaceI + bool faceProcessed = processSourceFace + ( + srcPatch, + tgtPatch, + srcFaceI, + tgtFaceI, - faceProcessed = true; - } + nbrFaces, + visitedFaces, - } while (nbrFaces.size() > 0); + srcAddr, + srcWght, + tgtAddr, + tgtWght + ); mapFlag[srcFaceI] = false; @@ -1140,6 +1301,22 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcAddressing srcNonOverlap_.transfer(nonOverlapFaces); } + + // Check for badly covered faces + if (debug) + { + restartUncoveredSourceFace + ( + srcPatch, + tgtPatch, + srcAddr, + srcWght, + tgtAddr, + tgtWght + ); + } + + // transfer data to persistent storage forAll(srcAddr, i) { diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H index b3930308235cd683803a4e56a90f32dabea11573..5b91afc38a9116299a1e75fd4b1132cec49131f7 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H @@ -246,6 +246,31 @@ class AMIInterpolation DynamicList<label>& faceIDs ) const; + bool processSourceFace + ( + const SourcePatch& srcPatch, + const TargetPatch& tgtPatch, + const label srcFaceI, + const label tgtStartFaceI, + + DynamicList<label>& nbrFaces, + DynamicList<label>& visitedFaces, + List<DynamicList<label> >& srcAddr, + List<DynamicList<scalar> >& srcWght, + List<DynamicList<label> >& tgtAddr, + List<DynamicList<scalar> >& tgtWght + ); + + void restartUncoveredSourceFace + ( + const SourcePatch& srcPatch, + const TargetPatch& tgtPatch, + List<DynamicList<label> >& srcAddr, + List<DynamicList<scalar> >& srcWght, + List<DynamicList<label> >& tgtAddr, + List<DynamicList<scalar> >& tgtWght + ); + //- Set the source and target seed faces void setNextFaces ( diff --git a/src/meshTools/AMIInterpolation/faceAreaIntersect/faceAreaIntersect.C b/src/meshTools/AMIInterpolation/faceAreaIntersect/faceAreaIntersect.C index db8a0ba294fec342f15a3d201e59a084efec48d4..4135cfe04191b4ffc2e2135c41dbf5b802a6b5dc 100644 --- a/src/meshTools/AMIInterpolation/faceAreaIntersect/faceAreaIntersect.C +++ b/src/meshTools/AMIInterpolation/faceAreaIntersect/faceAreaIntersect.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -25,6 +25,10 @@ License #include "faceAreaIntersect.H" +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +Foam::scalar Foam::faceAreaIntersect::tol = 1e-6; + // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // void Foam::faceAreaIntersect::triSliceWithPlane @@ -36,8 +40,6 @@ void Foam::faceAreaIntersect::triSliceWithPlane const scalar len ) { - const scalar matchTol = 1e-6; - // distance to cutting plane FixedList<scalar, 3> d; @@ -51,7 +53,7 @@ void Foam::faceAreaIntersect::triSliceWithPlane { d[i] = ((tri[i] - p.refPoint()) & p.normal()); - if (mag(d[i]) < matchTol*len) + if (mag(d[i]) < tol*len) { nCoPlanar++; copI = i; diff --git a/src/meshTools/AMIInterpolation/faceAreaIntersect/faceAreaIntersect.H b/src/meshTools/AMIInterpolation/faceAreaIntersect/faceAreaIntersect.H index 2a27e30960dee4d05235398e64bc53874817a8f1..bfbe7c08a2e2a1d31cbec044e7a01d12eea68399 100644 --- a/src/meshTools/AMIInterpolation/faceAreaIntersect/faceAreaIntersect.H +++ b/src/meshTools/AMIInterpolation/faceAreaIntersect/faceAreaIntersect.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -78,6 +78,11 @@ private: const bool reverseB_; + // Static data members + + static scalar tol; + + // Private Member Functions //- Get triPoints from face @@ -152,6 +157,9 @@ public: // Public Member Functions + //- Fraction of local length scale to use as intersection tolerance + inline static scalar& tolerance(); + //- Return area of intersection of faceA with faceB scalar calc ( diff --git a/src/meshTools/AMIInterpolation/faceAreaIntersect/faceAreaIntersectI.H b/src/meshTools/AMIInterpolation/faceAreaIntersect/faceAreaIntersectI.H index 0b8265aad66cb5e79b8a29f2adffb2cc92ab4e38..87fab781e075adea10d95d8e0d6f458ce063a5fc 100644 --- a/src/meshTools/AMIInterpolation/faceAreaIntersect/faceAreaIntersectI.H +++ b/src/meshTools/AMIInterpolation/faceAreaIntersect/faceAreaIntersectI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -23,6 +23,8 @@ License \*---------------------------------------------------------------------------*/ +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + inline void Foam::faceAreaIntersect::setTriPoints ( const point& a, @@ -106,4 +108,12 @@ inline Foam::scalar Foam::faceAreaIntersect::triArea(const triPoints& t) const } +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +Foam::scalar& Foam::faceAreaIntersect::tolerance() +{ + return tol; +} + + // ************************************************************************* // diff --git a/tutorials/compressible/rhoPimpleFoam/ras/angledDuct/constant/polyMesh/blockMeshDict.m4 b/tutorials/compressible/rhoPimpleFoam/ras/angledDuct/constant/polyMesh/blockMeshDict.m4 index 79da11e10ac8f655aa16fc6287c9496875d8672f..2e865a7856a7ac268e22302a7b752184d8bc0ba7 100644 --- a/tutorials/compressible/rhoPimpleFoam/ras/angledDuct/constant/polyMesh/blockMeshDict.m4 +++ b/tutorials/compressible/rhoPimpleFoam/ras/angledDuct/constant/polyMesh/blockMeshDict.m4 @@ -107,55 +107,79 @@ edges ( ); -patches +boundary ( // is there no way of defining all my 'defaultFaces' to be 'wall'? - wall front - ( - // inlet block - frontQuad(in1, join1, join2, in2) - // outlet block - frontQuad(poro1, out1, out2, poro2) - ) - - wall back - ( - // inlet block - backQuad(in1, join1, join2, in2) - // outlet block - backQuad(poro1, out1, out2, poro2) - ) - - wall wall - ( - // inlet block - quad2D(in1, join1) - quad2D(join2, in2) - // outlet block - quad2D(poro1, out1) - quad2D(out2, poro2) - ) - - wall porosityWall - ( - // porosity block - frontQuad(join1, poro1, poro2, join2) - // porosity block - backQuad(join1, poro1, poro2, join2) - // porosity block - quad2D(join1, poro1) - quad2D(poro2, join2) - ) - - patch inlet - ( - quad2D(in2, in1) - ) - - patch outlet - ( - quad2D(out2, out1) - ) + front + { + type wall; + faces + ( + // inlet block + frontQuad(in1, join1, join2, in2) + // outlet block + frontQuad(poro1, out1, out2, poro2) + ); + } + + back + { + type wall; + faces + ( + // inlet block + backQuad(in1, join1, join2, in2) + // outlet block + backQuad(poro1, out1, out2, poro2) + ); + } + + wall + { + type wall; + faces + ( + // inlet block + quad2D(in1, join1) + quad2D(join2, in2) + // outlet block + quad2D(poro1, out1) + quad2D(out2, poro2) + ); + } + + porosityWall + { + type wall; + faces + ( + // porosity block + frontQuad(join1, poro1, poro2, join2) + // porosity block + backQuad(join1, poro1, poro2, join2) + // porosity block + quad2D(join1, poro1) + quad2D(poro2, join2) + ); + } + + inlet + { + type patch; + faces + ( + quad2D(in2, in1) + ); + } + + outlet + { + type patch; + faces + ( + quad2D(out2, out1) + ); + } ); mergePatchPairs diff --git a/tutorials/compressible/rhoPimpleFoam/ras/angledDuct/constant/polyMesh/boundary b/tutorials/compressible/rhoPimpleFoam/ras/angledDuct/constant/polyMesh/boundary deleted file mode 100644 index 0abd1608aba0dcb6aa66c9488133a3c4b51c7588..0000000000000000000000000000000000000000 --- a/tutorials/compressible/rhoPimpleFoam/ras/angledDuct/constant/polyMesh/boundary +++ /dev/null @@ -1,58 +0,0 @@ -/*--------------------------------*- C++ -*----------------------------------*\ -| ========= | | -| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: dev | -| \\ / A nd | Web: www.OpenFOAM.org | -| \\/ M anipulation | | -\*---------------------------------------------------------------------------*/ -FoamFile -{ - version 2.0; - format ascii; - class polyBoundaryMesh; - location "constant/polyMesh"; - object boundary; -} -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -6 -( - front - { - type wall; - nFaces 700; - startFace 63400; - } - back - { - type wall; - nFaces 700; - startFace 64100; - } - wall - { - type wall; - nFaces 1400; - startFace 64800; - } - porosityWall - { - type wall; - nFaces 1600; - startFace 66200; - } - inlet - { - type patch; - nFaces 400; - startFace 67800; - } - outlet - { - type patch; - nFaces 400; - startFace 68200; - } -) - -// ************************************************************************* //