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

View File

@ -26,13 +26,12 @@ License
#include "patchCloudSet.H"
#include "polyMesh.H"
#include "addToRunTimeSelectionTable.H"
#include "pointIndexHit.H"
#include "Tuple2.H"
#include "treeBoundBox.H"
#include "indexedOctree.H"
#include "treeDataFace.H"
#include "Time.H"
#include "meshTools.H"
// For 'nearInfo' helper class only
#include "directMappedPatchBase.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -40,35 +39,6 @@ namespace Foam
{
defineTypeNameAndDebug(patchCloudSet, 0);
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;
}
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.max() = max(bb.max(), patchBb.max());
@ -125,6 +96,7 @@ void Foam::patchCloudSet::calcSamples
// Make bb asymetric just to avoid problems on symmetric meshes
bb = bb.extend(rndGen, 1E-4);
// Make sure bb is 3D.
bb.min() -= 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
List<nearInfo> nearest(sampleCoords_.size());
List<directMappedPatchBase::nearInfo> nearest(sampleCoords_.size());
forAll(sampleCoords_, sampleI)
{
@ -155,7 +127,15 @@ void Foam::patchCloudSet::calcSamples
pointIndexHit& nearInfo = nearest[sampleI].first();
// 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
if (!nearInfo.hit())
@ -179,7 +159,7 @@ void Foam::patchCloudSet::calcSamples
// Find nearest.
Pstream::listCombineGather(nearest, nearestEqOp());
Pstream::listCombineGather(nearest, directMappedPatchBase::nearestEqOp());
Pstream::listCombineScatter(nearest);
@ -197,6 +177,8 @@ void Foam::patchCloudSet::calcSamples
label vertI = 0;
forAll(nearest, i)
{
if (nearest[i].first().hit())
{
meshTools::writeOBJ(str, sampleCoords_[i]);
vertI++;
@ -205,15 +187,18 @@ void Foam::patchCloudSet::calcSamples
str << "l " << vertI-1 << ' ' << vertI << nl;
}
}
}
// Store the sampling locations on the nearest processor
forAll(nearest, sampleI)
{
if (nearest[sampleI].second().second() == Pstream::myProcNo())
{
const pointIndexHit& nearInfo = nearest[sampleI].first();
if (nearInfo.hit())
{
if (nearest[sampleI].second().second() == Pstream::myProcNo())
{
label faceI = nearInfo.index();
samplingPts.append(nearInfo.hitPoint());
@ -223,6 +208,20 @@ void Foam::patchCloudSet::calcSamples
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,
const word& axis,
const List<point>& sampleCoords,
const labelHashSet& patchSet
const labelHashSet& patchSet,
const scalar searchDist
)
:
sampledSet(name, mesh, searchEngine, axis),
sampleCoords_(sampleCoords),
patchSet_(patchSet)
patchSet_(patchSet),
searchDist_(searchDist)
{
genSamples();
@ -302,7 +303,8 @@ Foam::patchCloudSet::patchCloudSet
(
wordReList(dict.lookup("patches"))
)
)
),
searchDist_(readScalar(dict.lookup("maxDistance")))
{
genSamples();

View File

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

View File

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