ENH: support retention of original surface ids when sampling (related to issue #104)

For example,
    surfaces
    (
        helmet
        {
            type        sampledTriSurfaceMesh;
            surface     motorBike-passenger-helmet.obj;
            source      cells;
            keepIds     true;  <<-- NEW
        }
    );

    This will create an additional "Ids" field that can be used to sort
    or as a faceMap to recover the original face order.
This commit is contained in:
Mark Olesen
2016-11-29 17:14:56 +01:00
parent fbd4ff38b0
commit 690f58d2cb
6 changed files with 75 additions and 14 deletions

View File

@ -31,6 +31,7 @@ License
#include "volPointInterpolation.H" #include "volPointInterpolation.H"
#include "PatchTools.H" #include "PatchTools.H"
#include "mapPolyMesh.H" #include "mapPolyMesh.H"
#include "sampledTriSurfaceMesh.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -84,6 +85,37 @@ void Foam::sampledSurfaces::writeGeometry() const
} }
void Foam::sampledSurfaces::writeOriginalIds()
{
const word fieldName = "Ids";
const fileName outputDir = outputPath_/time_.timeName();
forAll(*this, surfI)
{
const sampledSurface& s = operator[](surfI);
if (isA<sampledTriSurfaceMesh>(s))
{
const sampledTriSurfaceMesh& surf =
dynamicCast<const sampledTriSurfaceMesh&>(s);
if (surf.keepIds())
{
const labelList& idLst = surf.originalIds();
Field<scalar> ids(idLst.size());
forAll(idLst, i)
{
ids[i] = idLst[i];
}
writeSurface(ids, surfI, fieldName, outputDir);
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::sampledSurfaces::sampledSurfaces Foam::sampledSurfaces::sampledSurfaces

View File

@ -116,6 +116,9 @@ class sampledSurfaces
//- Write geometry only //- Write geometry only
void writeGeometry() const; void writeGeometry() const;
//- Write scalar field with original ids
void writeOriginalIds();
//- Write sampled fieldName on surface and on outputDir path //- Write sampled fieldName on surface and on outputDir path
template<class Type> template<class Type>
void writeSurface void writeSurface

View File

@ -60,7 +60,6 @@ Foam::label Foam::sampledSurfaces::classifyFields()
{ {
// Check currently available fields // Check currently available fields
wordList allFields = obr_.sortedNames(); wordList allFields = obr_.sortedNames();
labelList indices = findStrings(fieldSelection_, allFields);
forAll(fieldSelection_, i) forAll(fieldSelection_, i)
{ {

View File

@ -49,9 +49,7 @@ void Foam::sampledSurfaces::writeSurface
gatheredValues[Pstream::myProcNo()] = values; gatheredValues[Pstream::myProcNo()] = values;
Pstream::gatherList(gatheredValues); Pstream::gatherList(gatheredValues);
fileName sampleFile; fileName sampleFile;
if (Pstream::master()) if (Pstream::master())
{ {
// Combine values into single field // Combine values into single field
@ -181,24 +179,21 @@ void Foam::sampledSurfaces::sampleAndWrite
template<class GeoField> template<class GeoField>
void Foam::sampledSurfaces::sampleAndWrite(const IOobjectList& objects) void Foam::sampledSurfaces::sampleAndWrite(const IOobjectList& objects)
{ {
wordList names; wordList fieldNames;
if (loadFromFiles_) if (loadFromFiles_)
{ {
IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName)); fieldNames = objects.sortedNames(GeoField::typeName, fieldSelection_);
names = fieldObjects.names();
} }
else else
{ {
names = mesh_.thisDb().names<GeoField>(); fieldNames = mesh_.thisDb().sortedNames<GeoField>(fieldSelection_);
writeOriginalIds();
} }
labelList nameIDs(findStrings(fieldSelection_, names)); forAll(fieldNames, fieldi)
wordHashSet fieldNames(wordList(names, nameIDs));
forAllConstIter(wordHashSet, fieldNames, iter)
{ {
const word& fieldName = iter.key(); const word& fieldName = fieldNames[fieldi];
if ((Pstream::master()) && verbose_) if ((Pstream::master()) && verbose_)
{ {

View File

@ -296,6 +296,11 @@ bool Foam::sampledTriSurfaceMesh::update(const meshSearch& meshSearcher)
} }
if (keepIds_)
{
originalIds_ = faceMap;
}
// Subset cellOrFaceLabels // Subset cellOrFaceLabels
cellOrFaceLabels = UIndirectList<label>(cellOrFaceLabels, faceMap)(); cellOrFaceLabels = UIndirectList<label>(cellOrFaceLabels, faceMap)();
@ -545,6 +550,8 @@ Foam::sampledTriSurfaceMesh::sampledTriSurfaceMesh
), ),
sampleSource_(sampleSource), sampleSource_(sampleSource),
needsUpdate_(true), needsUpdate_(true),
keepIds_(false),
originalIds_(),
sampleElements_(0), sampleElements_(0),
samplePoints_(0) samplePoints_(0)
{} {}
@ -573,6 +580,8 @@ Foam::sampledTriSurfaceMesh::sampledTriSurfaceMesh
), ),
sampleSource_(samplingSourceNames_[dict.lookup("source")]), sampleSource_(samplingSourceNames_[dict.lookup("source")]),
needsUpdate_(true), needsUpdate_(true),
keepIds_(dict.lookupOrDefault<Switch>("keepIds", false)),
originalIds_(),
sampleElements_(0), sampleElements_(0),
samplePoints_(0) samplePoints_(0)
{} {}
@ -594,7 +603,7 @@ Foam::sampledTriSurfaceMesh::sampledTriSurfaceMesh
name, name,
mesh.time().constant(), // instance mesh.time().constant(), // instance
"triSurface", // local "triSurface", // local
mesh, // registry mesh, // registry
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
false false
@ -603,6 +612,8 @@ Foam::sampledTriSurfaceMesh::sampledTriSurfaceMesh
), ),
sampleSource_(samplingSourceNames_[sampleSourceName]), sampleSource_(samplingSourceNames_[sampleSourceName]),
needsUpdate_(true), needsUpdate_(true),
keepIds_(false),
originalIds_(),
sampleElements_(0), sampleElements_(0),
samplePoints_(0) samplePoints_(0)
{} {}
@ -633,6 +644,7 @@ bool Foam::sampledTriSurfaceMesh::expire()
sampledSurface::clearGeom(); sampledSurface::clearGeom();
MeshStorage::clear(); MeshStorage::clear();
originalIds_.clear();
boundaryTreePtr_.clear(); boundaryTreePtr_.clear();
sampleElements_.clear(); sampleElements_.clear();
samplePoints_.clear(); samplePoints_.clear();

View File

@ -117,6 +117,13 @@ private:
//- Track if the surface needs an update //- Track if the surface needs an update
mutable bool needsUpdate_; mutable bool needsUpdate_;
//- Retain element ids/order of original surface
bool keepIds_;
//- List of element ids/order of the original surface,
// when keepIds is active.
labelList originalIds_;
//- Search tree for all non-coupled boundary faces //- Search tree for all non-coupled boundary faces
mutable autoPtr<indexedOctree<treeDataFace>> boundaryTreePtr_; mutable autoPtr<indexedOctree<treeDataFace>> boundaryTreePtr_;
@ -240,6 +247,19 @@ public:
return MeshStorage::Cf(); return MeshStorage::Cf();
} }
//- If element ids/order of the original surface are kept
bool keepIds() const
{
return keepIds_;
}
//- List of element ids/order of the original surface,
// when keepIds is active.
const labelList& originalIds() const
{
return originalIds_;
}
//- Sample field on surface //- Sample field on surface
virtual tmp<scalarField> sample virtual tmp<scalarField> sample