ENH: patchCloud: return pTraits<Type>::max for unfound points

This commit is contained in:
mattijs
2011-07-14 22:10:14 +01:00
parent 81c2d88bd3
commit e47ac108ee
4 changed files with 101 additions and 74 deletions

View File

@ -119,15 +119,18 @@ sets
somePatchPoints somePatchPoints
{ {
// Sample nearest points on selected patches. Use with // Sample nearest points on selected patches. Looks only up to
// interpolations: // maxDistance away. Any sampling point not found will get value
// pTraits<Type>::max (usually VGREAT)
// Use with interpolations:
// - cell (cell value) // - cell (cell value)
// - cellPatchConstrained (boundary value) // - cellPatchConstrained (boundary value)
// - cellPoint (interpolated boundary value) // - cellPoint (interpolated boundary value)
type patchCloud; type patchCloud;
axis xyz; axis xyz;
points ((0.049 0.099 0.005)(0.051 0.054 0.005)); points ((0.049 0.099 0.005)(0.051 0.054 0.005));
patches (".*Wall.*"); maxDistance 0.1; // maximum distance to search
patches (".*Wall.*");
} }
); );

View File

@ -26,13 +26,12 @@ License
#include "patchCloudSet.H" #include "patchCloudSet.H"
#include "polyMesh.H" #include "polyMesh.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
#include "pointIndexHit.H"
#include "Tuple2.H"
#include "treeBoundBox.H" #include "treeBoundBox.H"
#include "indexedOctree.H"
#include "treeDataFace.H" #include "treeDataFace.H"
#include "Time.H" #include "Time.H"
#include "meshTools.H" #include "meshTools.H"
// For 'nearInfo' helper class only
#include "directMappedPatchBase.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -40,35 +39,6 @@ namespace Foam
{ {
defineTypeNameAndDebug(patchCloudSet, 0); defineTypeNameAndDebug(patchCloudSet, 0);
addToRunTimeSelectionTable(sampledSet, patchCloudSet, word); addToRunTimeSelectionTable(sampledSet, patchCloudSet, word);
//- Helper class for finding nearest
// Nearest:
// - point+local index
// - sqr(distance)
// - processor
typedef Tuple2<pointIndexHit, Tuple2<scalar, label> > nearInfo;
class nearestEqOp
{
public:
void operator()(nearInfo& x, const nearInfo& y) const
{
if (y.first().hit())
{
if (!x.first().hit())
{
x = y;
}
else if (y.second().first() < x.second().first())
{
x = y;
}
}
}
};
} }
@ -114,7 +84,8 @@ void Foam::patchCloudSet::calcSamples
patchFaces[sz++] = pp.start()+i; patchFaces[sz++] = pp.start()+i;
} }
const boundBox patchBb(pp.points(), pp.meshPoints()); // Do not do reduction.
const boundBox patchBb(pp.points(), pp.meshPoints(), false);
bb.min() = min(bb.min(), patchBb.min()); bb.min() = min(bb.min(), patchBb.min());
bb.max() = max(bb.max(), patchBb.max()); bb.max() = max(bb.max(), patchBb.max());
@ -125,6 +96,7 @@ void Foam::patchCloudSet::calcSamples
// Make bb asymetric just to avoid problems on symmetric meshes // Make bb asymetric just to avoid problems on symmetric meshes
bb = bb.extend(rndGen, 1E-4); bb = bb.extend(rndGen, 1E-4);
// Make sure bb is 3D.
bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
@ -146,7 +118,7 @@ void Foam::patchCloudSet::calcSamples
// All the info for nearest. Construct to miss // All the info for nearest. Construct to miss
List<nearInfo> nearest(sampleCoords_.size()); List<directMappedPatchBase::nearInfo> nearest(sampleCoords_.size());
forAll(sampleCoords_, sampleI) forAll(sampleCoords_, sampleI)
{ {
@ -155,7 +127,15 @@ void Foam::patchCloudSet::calcSamples
pointIndexHit& nearInfo = nearest[sampleI].first(); pointIndexHit& nearInfo = nearest[sampleI].first();
// Find the nearest locally // Find the nearest locally
nearInfo = patchTree.findNearest(sample, magSqr(bb.span())); if (patchFaces.size())
{
nearInfo = patchTree.findNearest(sample, sqr(searchDist_));
}
else
{
nearInfo.setMiss();
}
// Fill in the distance field and the processor field // Fill in the distance field and the processor field
if (!nearInfo.hit()) if (!nearInfo.hit())
@ -179,7 +159,7 @@ void Foam::patchCloudSet::calcSamples
// Find nearest. // Find nearest.
Pstream::listCombineGather(nearest, nearestEqOp()); Pstream::listCombineGather(nearest, directMappedPatchBase::nearestEqOp());
Pstream::listCombineScatter(nearest); Pstream::listCombineScatter(nearest);
@ -198,11 +178,14 @@ void Foam::patchCloudSet::calcSamples
forAll(nearest, i) forAll(nearest, i)
{ {
meshTools::writeOBJ(str, sampleCoords_[i]); if (nearest[i].first().hit())
vertI++; {
meshTools::writeOBJ(str, nearest[i].first().hitPoint()); meshTools::writeOBJ(str, sampleCoords_[i]);
vertI++; vertI++;
str << "l " << vertI-1 << ' ' << vertI << nl; meshTools::writeOBJ(str, nearest[i].first().hitPoint());
vertI++;
str << "l " << vertI-1 << ' ' << vertI << nl;
}
} }
} }
@ -210,17 +193,33 @@ void Foam::patchCloudSet::calcSamples
// Store the sampling locations on the nearest processor // Store the sampling locations on the nearest processor
forAll(nearest, sampleI) forAll(nearest, sampleI)
{ {
if (nearest[sampleI].second().second() == Pstream::myProcNo()) const pointIndexHit& nearInfo = nearest[sampleI].first();
if (nearInfo.hit())
{ {
const pointIndexHit& nearInfo = nearest[sampleI].first(); if (nearest[sampleI].second().second() == Pstream::myProcNo())
{
label faceI = nearInfo.index();
label faceI = nearInfo.index(); samplingPts.append(nearInfo.hitPoint());
samplingCells.append(mesh().faceOwner()[faceI]);
samplingPts.append(nearInfo.hitPoint()); samplingFaces.append(faceI);
samplingCells.append(mesh().faceOwner()[faceI]); samplingSegments.append(0);
samplingFaces.append(faceI); samplingCurveDist.append(1.0 * sampleI);
samplingSegments.append(0); }
samplingCurveDist.append(1.0 * sampleI); }
else
{
// No processor found point near enough. Mark with special value
// which is intercepted when interpolating
if (Pstream::master())
{
samplingPts.append(sampleCoords_[sampleI]);
samplingCells.append(-1);
samplingFaces.append(-1);
samplingSegments.append(0);
samplingCurveDist.append(1.0 * sampleI);
}
} }
} }
} }
@ -270,12 +269,14 @@ Foam::patchCloudSet::patchCloudSet
meshSearch& searchEngine, meshSearch& searchEngine,
const word& axis, const word& axis,
const List<point>& sampleCoords, const List<point>& sampleCoords,
const labelHashSet& patchSet const labelHashSet& patchSet,
const scalar searchDist
) )
: :
sampledSet(name, mesh, searchEngine, axis), sampledSet(name, mesh, searchEngine, axis),
sampleCoords_(sampleCoords), sampleCoords_(sampleCoords),
patchSet_(patchSet) patchSet_(patchSet),
searchDist_(searchDist)
{ {
genSamples(); genSamples();
@ -302,7 +303,8 @@ Foam::patchCloudSet::patchCloudSet
( (
wordReList(dict.lookup("patches")) wordReList(dict.lookup("patches"))
) )
) ),
searchDist_(readScalar(dict.lookup("maxDistance")))
{ {
genSamples(); genSamples();

View File

@ -56,10 +56,14 @@ class patchCloudSet
// Private data // Private data
//- Sampling points //- Sampling points
List<point> sampleCoords_; const List<point> sampleCoords_;
//- Patches to sample //- Patches to sample
labelHashSet patchSet_; const labelHashSet patchSet_;
//- Maximum distance to look for nearest
const scalar searchDist_;
// Private Member Functions // Private Member Functions
@ -93,7 +97,8 @@ public:
meshSearch& searchEngine, meshSearch& searchEngine,
const word& axis, const word& axis,
const List<point>& sampleCoords, const List<point>& sampleCoords,
const labelHashSet& patchSet const labelHashSet& patchSet,
const scalar searchDist
); );
//- Construct from dictionary //- Construct from dictionary

View File

@ -51,18 +51,26 @@ Foam::sampledSets::volFieldSampler<Type>::volFieldSampler
const sampledSet& samples = samplers[setI]; const sampledSet& samples = samplers[setI];
values.setSize(samples.size()); values.setSize(samples.size());
forAll(samples, samplei) forAll(samples, sampleI)
{ {
const point& samplePt = samples[samplei]; const point& samplePt = samples[sampleI];
label celli = samples.cells()[samplei]; label cellI = samples.cells()[sampleI];
label facei = samples.faces()[samplei]; label faceI = samples.faces()[sampleI];
values[samplei] = interpolator().interpolate if (cellI == -1 && faceI == -1)
( {
samplePt, // Special condition for illegal sampling points
celli, values[sampleI] = pTraits<Type>::max;
facei }
); else
{
values[sampleI] = interpolator().interpolate
(
samplePt,
cellI,
faceI
);
}
} }
} }
} }
@ -84,9 +92,18 @@ Foam::sampledSets::volFieldSampler<Type>::volFieldSampler
const sampledSet& samples = samplers[setI]; const sampledSet& samples = samplers[setI];
values.setSize(samples.size()); values.setSize(samples.size());
forAll(samples, samplei) forAll(samples, sampleI)
{ {
values[samplei] = field[samples.cells()[samplei]]; label cellI = samples.cells()[sampleI];
if (cellI ==-1)
{
values[sampleI] = pTraits<Type>::max;
}
else
{
values[sampleI] = field[cellI];
}
} }
} }
} }