diff --git a/ReleaseNotes-dev b/ReleaseNotes-dev index a19af405e7..fa80518f35 100644 --- a/ReleaseNotes-dev +++ b/ReleaseNotes-dev @@ -240,11 +240,14 @@ + =snappyHexMesh=: + extrude across multi-processor boundaries + preserve faceZones during layering + + combining patch faces after snapping + *Warning*: - minMedianAxisAngle angle fixed w.r.t. 17x. Set to 90 to get same behaviour as 130 in 17x. - nGrow did not work in 17x. Set to 0 to get same behaviour as 130 in 17x. + - nSolveIter reinstated to smooth internal mesh. Set to 0 + to get same behaviour at 17x. - new minTetQuality setting (see tracking). Disable for 17x compatibility. * Post-processing diff --git a/applications/utilities/postProcessing/sampling/sample/sampleDict b/applications/utilities/postProcessing/sampling/sample/sampleDict index c34ce71daf..b983a35a11 100644 --- a/applications/utilities/postProcessing/sampling/sample/sampleDict +++ b/applications/utilities/postProcessing/sampling/sample/sampleDict @@ -150,29 +150,29 @@ surfaces interpolate true; } - movingWall_constant + walls_constant { type patch; - patchName movingWall; + patches ( ".*Wall.*" ); // Optional: whether to leave as faces (=default) or triangulate // triangulate false; } - movingWall_interpolated + walls_interpolated { type patch; - patchName movingWall; + patches ( ".*Wall.*" ); interpolate true; // Optional: whether to leave as faces (=default) or triangulate // triangulate false; } - movingNearWall_interpolated + nearWalls_interpolated { // Sample cell values off patch. Does not need to be the near-wall // cell, can be arbitrarily far away. type patchInternalField; - patchName movingWall; + patches ( ".*Wall.*" ); distance 0.0001; interpolate true; // Optional: whether to leave as faces (=default) or triangulate diff --git a/src/lagrangian/basic/particle/particleI.H b/src/lagrangian/basic/particle/particleI.H index 79d2315662..a11018a5d5 100644 --- a/src/lagrangian/basic/particle/particleI.H +++ b/src/lagrangian/basic/particle/particleI.H @@ -97,12 +97,19 @@ inline Foam::scalar Foam::particle::tetLambda scalar lambdaNumerator = (base - from) & n; scalar lambdaDenominator = (to - from) & n; - if (mag(lambdaDenominator) < SMALL) + // n carries the area of the tet faces, so the dot product with a + // delta-length has the units of volume. Comparing the component of each + // delta-length in the direction of n times the face area to a fraction of + // the cell volume. + + scalar tol = 1e3*SMALL*mesh_.cellVolumes()[cellI]; + + if (mag(lambdaDenominator) < tol) { - if (mag(lambdaNumerator) < SMALL) + if (mag(lambdaNumerator) < tol) { // Track starts on the face, and is potentially - // parallel to it. +-SMALL/+-SMALL is not a good + // parallel to it. +-tol/+-tol is not a good // comparison, return 0.0, in anticipation of tet // centre correction. @@ -110,10 +117,11 @@ inline Foam::scalar Foam::particle::tetLambda } else { - if (mag((to - from)) < SMALL) + if (mag((to - from)) < tol/mag(n)) { - // Zero length track, not along the face, face - // cannot be crossed. + // 'Zero' length track (compared to the tolerance, which is + // based on the cell volume, divided by the tet face area), not + // along the face, face cannot be crossed. return GREAT; } @@ -291,12 +299,14 @@ inline Foam::scalar Foam::particle::movingTetLambda } - if (mag(lambdaDenominator) < SMALL) + scalar tol = 1e3*SMALL*mesh_.cellVolumes()[cellI]; + + if (mag(lambdaDenominator) < tol) { - if (mag(lambdaNumerator) < SMALL) + if (mag(lambdaNumerator) < tol) { // Track starts on the face, and is potentially - // parallel to it. +-SMALL)/+-SMALL is not a good + // parallel to it. +-tol)/+-tol is not a good // comparison, return 0.0, in anticipation of tet // centre correction. @@ -304,7 +314,7 @@ inline Foam::scalar Foam::particle::movingTetLambda } else { - if (mag((to - from)) < SMALL) + if (mag((to - from)) < tol/mag(n)) { // Zero length track, not along the face, face // cannot be crossed. diff --git a/src/lagrangian/basic/particle/particleTemplates.C b/src/lagrangian/basic/particle/particleTemplates.C index 2f8053677b..e77376150a 100644 --- a/src/lagrangian/basic/particle/particleTemplates.C +++ b/src/lagrangian/basic/particle/particleTemplates.C @@ -30,6 +30,7 @@ License #include "symmetryPolyPatch.H" #include "wallPolyPatch.H" #include "wedgePolyPatch.H" +#include "meshTools.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -463,7 +464,7 @@ Foam::scalar Foam::particle::trackToFace // << origId_ << " " << origProc_<< nl // << "# face: " << tetFaceI_ << nl // << "# tetPtI: " << tetPtI_ << nl - // << "# tetBasePtI: " << mesh.tetBasePtIs()[tetFaceI_] << nl + // << "# tetBasePtI: " << mesh_.tetBasePtIs()[tetFaceI_] << nl // << "# tet.mag(): " << tet.mag() << nl // << "# tet.quality(): " << tet.quality() // << endl; diff --git a/src/sampling/sampledSurface/sampledPatch/sampledPatch.C b/src/sampling/sampledSurface/sampledPatch/sampledPatch.C index 97ca76f68c..6f180dcd86 100644 --- a/src/sampling/sampledSurface/sampledPatch/sampledPatch.C +++ b/src/sampling/sampledSurface/sampledPatch/sampledPatch.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -46,15 +46,14 @@ Foam::sampledPatch::sampledPatch ( const word& name, const polyMesh& mesh, - const word& patchName, + const wordReList& patchNames, const bool triangulate ) : sampledSurface(name, mesh), - patchName_(patchName), + patchNames_(patchNames), triangulate_(triangulate), - needsUpdate_(true), - patchFaceLabels_(0) + needsUpdate_(true) {} @@ -66,10 +65,9 @@ Foam::sampledPatch::sampledPatch ) : sampledSurface(name, mesh, dict), - patchName_(dict.lookup("patchName")), + patchNames_(dict.lookup("patches")), triangulate_(dict.lookupOrDefault("triangulate", false)), - needsUpdate_(true), - patchFaceLabels_(0) + needsUpdate_(true) {} @@ -81,6 +79,20 @@ Foam::sampledPatch::~sampledPatch() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +const Foam::labelList& Foam::sampledPatch::patchIDs() const +{ + if (patchIDs_.empty()) + { + patchIDs_ = mesh().boundaryMesh().patchSet + ( + patchNames_, + false + ).sortedToc(); + } + return patchIDs_; +} + + bool Foam::sampledPatch::needsUpdate() const { return needsUpdate_; @@ -97,7 +109,10 @@ bool Foam::sampledPatch::expire() sampledSurface::clearGeom(); MeshStorage::clear(); + patchIDs_.clear(); + patchIndex_.clear(); patchFaceLabels_.clear(); + patchStart_.clear(); needsUpdate_ = true; return true; @@ -111,31 +126,67 @@ bool Foam::sampledPatch::update() return false; } - const label patchI = mesh().boundaryMesh().findPatchID(patchName_); - - if (patchI != -1) + label sz = 0; + forAll(patchIDs(), i) { - const polyPatch& p = mesh().boundaryMesh()[patchI]; - this->storedPoints() = p.localPoints(); - this->storedFaces() = p.localFaces(); + label patchI = patchIDs()[i]; + const polyPatch& pp = mesh().boundaryMesh()[patchI]; - // an identity map - patchFaceLabels_.setSize(faces().size()); - forAll(patchFaceLabels_, i) + if (isA(pp)) { - patchFaceLabels_[i] = i; + FatalErrorIn("sampledPatch::update()") + << "Cannot sample an empty patch. Patch " << pp.name() + << exit(FatalError); } - // triangulate uses remapFaces() - // - this is somewhat less efficient since it recopies the faces - // that we just created, but we probably don't want to do this - // too often anyhow. - if (triangulate_) + sz += pp.size(); + } + + // For every face (or triangle) the originating patch and local face in the + // patch. + patchIndex_.setSize(sz); + patchFaceLabels_.setSize(sz); + patchStart_.setSize(patchIDs().size()); + labelList meshFaceLabels(sz); + + sz = 0; + + forAll(patchIDs(), i) + { + label patchI = patchIDs()[i]; + + patchStart_[i] = sz; + + const polyPatch& pp = mesh().boundaryMesh()[patchI]; + + forAll(pp, j) { - MeshStorage::triangulate(); + patchIndex_[sz] = i; + patchFaceLabels_[sz] = j; + meshFaceLabels[sz] = pp.start()+j; + sz++; } } + indirectPrimitivePatch allPatches + ( + IndirectList(mesh().faces(), meshFaceLabels), + mesh().points() + ); + + this->storedPoints() = allPatches.localPoints(); + this->storedFaces() = allPatches.localFaces(); + + + // triangulate uses remapFaces() + // - this is somewhat less efficient since it recopies the faces + // that we just created, but we probably don't want to do this + // too often anyhow. + if (triangulate_) + { + MeshStorage::triangulate(); + } + if (debug) { print(Pout); @@ -148,10 +199,7 @@ bool Foam::sampledPatch::update() // remap action on triangulation -void Foam::sampledPatch::remapFaces -( - const labelUList& faceMap -) +void Foam::sampledPatch::remapFaces(const labelUList& faceMap) { // recalculate the cells cut if (&faceMap && faceMap.size()) @@ -161,11 +209,27 @@ void Foam::sampledPatch::remapFaces ( UIndirectList