ENH: sampledPatch: patchSet instead of single patch

This commit is contained in:
mattijs
2011-04-05 20:54:18 +01:00
parent f203f4a835
commit b09a19e026
11 changed files with 247 additions and 131 deletions

View File

@ -150,29 +150,29 @@ surfaces
interpolate true; interpolate true;
} }
movingWall_constant walls_constant
{ {
type patch; type patch;
patchName movingWall; patches ( ".*Wall.*" );
// Optional: whether to leave as faces (=default) or triangulate // Optional: whether to leave as faces (=default) or triangulate
// triangulate false; // triangulate false;
} }
movingWall_interpolated walls_interpolated
{ {
type patch; type patch;
patchName movingWall; patches ( ".*Wall.*" );
interpolate true; interpolate true;
// Optional: whether to leave as faces (=default) or triangulate // Optional: whether to leave as faces (=default) or triangulate
// triangulate false; // triangulate false;
} }
movingNearWall_interpolated nearWalls_interpolated
{ {
// Sample cell values off patch. Does not need to be the near-wall // Sample cell values off patch. Does not need to be the near-wall
// cell, can be arbitrarily far away. // cell, can be arbitrarily far away.
type patchInternalField; type patchInternalField;
patchName movingWall; patches ( ".*Wall.*" );
distance 0.0001; distance 0.0001;
interpolate true; interpolate true;
// Optional: whether to leave as faces (=default) or triangulate // Optional: whether to leave as faces (=default) or triangulate

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -46,15 +46,14 @@ Foam::sampledPatch::sampledPatch
( (
const word& name, const word& name,
const polyMesh& mesh, const polyMesh& mesh,
const word& patchName, const wordReList& patchNames,
const bool triangulate const bool triangulate
) )
: :
sampledSurface(name, mesh), sampledSurface(name, mesh),
patchName_(patchName), patchNames_(patchNames),
triangulate_(triangulate), triangulate_(triangulate),
needsUpdate_(true), needsUpdate_(true)
patchFaceLabels_(0)
{} {}
@ -66,10 +65,9 @@ Foam::sampledPatch::sampledPatch
) )
: :
sampledSurface(name, mesh, dict), sampledSurface(name, mesh, dict),
patchName_(dict.lookup("patchName")), patchNames_(dict.lookup("patches")),
triangulate_(dict.lookupOrDefault("triangulate", false)), triangulate_(dict.lookupOrDefault("triangulate", false)),
needsUpdate_(true), needsUpdate_(true)
patchFaceLabels_(0)
{} {}
@ -81,6 +79,20 @@ Foam::sampledPatch::~sampledPatch()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * 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 bool Foam::sampledPatch::needsUpdate() const
{ {
return needsUpdate_; return needsUpdate_;
@ -97,7 +109,10 @@ bool Foam::sampledPatch::expire()
sampledSurface::clearGeom(); sampledSurface::clearGeom();
MeshStorage::clear(); MeshStorage::clear();
patchIDs_.clear();
patchIndex_.clear();
patchFaceLabels_.clear(); patchFaceLabels_.clear();
patchStart_.clear();
needsUpdate_ = true; needsUpdate_ = true;
return true; return true;
@ -111,21 +126,58 @@ bool Foam::sampledPatch::update()
return false; return false;
} }
const label patchI = mesh().boundaryMesh().findPatchID(patchName_); label sz = 0;
forAll(patchIDs(), i)
if (patchI != -1)
{ {
const polyPatch& p = mesh().boundaryMesh()[patchI]; label patchI = patchIDs()[i];
this->storedPoints() = p.localPoints(); const polyPatch& pp = mesh().boundaryMesh()[patchI];
this->storedFaces() = p.localFaces();
// an identity map if (isA<emptyPolyPatch>(pp))
patchFaceLabels_.setSize(faces().size());
forAll(patchFaceLabels_, i)
{ {
patchFaceLabels_[i] = i; FatalErrorIn("sampledPatch::update()")
<< "Cannot sample an empty patch. Patch " << pp.name()
<< exit(FatalError);
} }
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)
{
patchIndex_[sz] = i;
patchFaceLabels_[sz] = j;
meshFaceLabels[sz] = pp.start()+j;
sz++;
}
}
indirectPrimitivePatch allPatches
(
IndirectList<face>(mesh().faces(), meshFaceLabels),
mesh().points()
);
this->storedPoints() = allPatches.localPoints();
this->storedFaces() = allPatches.localFaces();
// triangulate uses remapFaces() // triangulate uses remapFaces()
// - this is somewhat less efficient since it recopies the faces // - this is somewhat less efficient since it recopies the faces
// that we just created, but we probably don't want to do this // that we just created, but we probably don't want to do this
@ -134,7 +186,6 @@ bool Foam::sampledPatch::update()
{ {
MeshStorage::triangulate(); MeshStorage::triangulate();
} }
}
if (debug) if (debug)
{ {
@ -148,10 +199,7 @@ bool Foam::sampledPatch::update()
// remap action on triangulation // remap action on triangulation
void Foam::sampledPatch::remapFaces void Foam::sampledPatch::remapFaces(const labelUList& faceMap)
(
const labelUList& faceMap
)
{ {
// recalculate the cells cut // recalculate the cells cut
if (&faceMap && faceMap.size()) if (&faceMap && faceMap.size())
@ -161,11 +209,27 @@ void Foam::sampledPatch::remapFaces
( (
UIndirectList<label>(patchFaceLabels_, faceMap) UIndirectList<label>(patchFaceLabels_, faceMap)
); );
patchIndex_ = labelList
(
UIndirectList<label>(patchIndex_, faceMap)
);
// Redo patchStart.
if (patchIndex_.size() > 0)
{
patchStart_[patchIndex_[0]] = 0;
for (label i = 1; i < patchIndex_.size(); i++)
{
if (patchIndex_[i] != patchIndex_[i-1])
{
patchStart_[patchIndex_[i]] = i;
}
}
}
} }
} }
Foam::tmp<Foam::scalarField> Foam::sampledPatch::sample Foam::tmp<Foam::scalarField> Foam::sampledPatch::sample
( (
const volScalarField& vField const volScalarField& vField
@ -257,7 +321,7 @@ Foam::tmp<Foam::tensorField> Foam::sampledPatch::interpolate
void Foam::sampledPatch::print(Ostream& os) const void Foam::sampledPatch::print(Ostream& os) const
{ {
os << "sampledPatch: " << name() << " :" os << "sampledPatch: " << name() << " :"
<< " patch:" << patchName() << " patches:" << patchNames()
<< " faces:" << faces().size() << " faces:" << faces().size()
<< " points:" << points().size(); << " points:" << points().size();
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -25,7 +25,7 @@ Class
Foam::sampledPatch Foam::sampledPatch
Description Description
A sampledSurface on a patch. Non-triangulated by default. A sampledSurface on patches. Non-triangulated by default.
SourceFiles SourceFiles
sampledPatch.C sampledPatch.C
@ -57,8 +57,11 @@ class sampledPatch
// Private data // Private data
//- Name of patch //- Name of patches
const word patchName_; const wordReList patchNames_;
//- Corresponding patchIDs
mutable labelList patchIDs_;
//- Triangulated faces or keep faces as is //- Triangulated faces or keep faces as is
bool triangulate_; bool triangulate_;
@ -66,11 +69,16 @@ class sampledPatch
//- Track if the surface needs an update //- Track if the surface needs an update
mutable bool needsUpdate_; mutable bool needsUpdate_;
//- Local patch face labels //- For every face (or triangle) the originating patch
labelList patchIndex_;
//- For every face (or triangle) the index in the originating patch
labelList patchFaceLabels_; labelList patchFaceLabels_;
// Private Member Functions //- Start indices (in patchFaceLabels_) of patches
labelList patchStart_;
// Private Member Functions
//- sample field on faces //- sample field on faces
template <class Type> template <class Type>
@ -79,15 +87,34 @@ class sampledPatch
const GeometricField<Type, fvPatchField, volMesh>& vField const GeometricField<Type, fvPatchField, volMesh>& vField
) const; ) const;
template <class Type> template <class Type>
tmp<Field<Type> > tmp<Field<Type> >
interpolateField(const interpolation<Type>&) const; interpolateField(const interpolation<Type>&) const;
//- remap action on triangulation or cleanup //- remap action on triangulation or cleanup
virtual void remapFaces(const labelUList& faceMap); virtual void remapFaces(const labelUList& faceMap);
protected:
const wordReList& patchNames() const
{
return patchNames_;
}
const labelList& patchIDs() const;
const labelList& patchStart() const
{
return patchStart_;
}
const labelList& patchFaceLabels() const
{
return patchFaceLabels_;
}
public: public:
//- Runtime type information //- Runtime type information
@ -101,7 +128,7 @@ public:
( (
const word& name, const word& name,
const polyMesh& mesh, const polyMesh& mesh,
const word& patchName, const wordReList& patchNames,
const bool triangulate = false const bool triangulate = false
); );
@ -133,21 +160,6 @@ public:
virtual bool update(); virtual bool update();
const word patchName() const
{
return patchName_;
}
label patchIndex() const
{
return mesh().boundaryMesh().findPatchID(patchName_);
}
const labelList& patchFaceLabels() const
{
return patchFaceLabels_;
}
//- Points of surface //- Points of surface
virtual const pointField& points() const virtual const pointField& points() const
{ {

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -37,15 +37,11 @@ Foam::sampledPatch::sampleField
// One value per face // One value per face
tmp<Field<Type> > tvalues(new Field<Type>(patchFaceLabels_.size())); tmp<Field<Type> > tvalues(new Field<Type>(patchFaceLabels_.size()));
Field<Type>& values = tvalues(); Field<Type>& values = tvalues();
forAll(patchFaceLabels_, i)
if (patchIndex() != -1)
{ {
const Field<Type>& bField = vField.boundaryField()[patchIndex()]; label patchI = patchIDs_[patchIndex_[i]];
const Field<Type>& bField = vField.boundaryField()[patchI];
forAll(patchFaceLabels_, elemI) values[i] = bField[patchFaceLabels_[i]];
{
values[elemI] = bField[patchFaceLabels_[elemI]];
}
} }
return tvalues; return tvalues;
@ -63,15 +59,15 @@ Foam::sampledPatch::interpolateField
tmp<Field<Type> > tvalues(new Field<Type>(points().size())); tmp<Field<Type> > tvalues(new Field<Type>(points().size()));
Field<Type>& values = tvalues(); Field<Type>& values = tvalues();
if (patchIndex() != -1)
{
const polyPatch& patch = mesh().boundaryMesh()[patchIndex()];
const labelList& own = mesh().faceOwner(); const labelList& own = mesh().faceOwner();
boolList pointDone(points().size(), false); boolList pointDone(points().size(), false);
forAll(faces(), cutFaceI) forAll(faces(), cutFaceI)
{ {
label patchI = patchIDs_[patchIndex_[cutFaceI]];
const polyPatch& pp = mesh().boundaryMesh()[patchI];
label patchFaceI = patchFaceLabels()[cutFaceI];
const face& f = faces()[cutFaceI]; const face& f = faces()[cutFaceI];
forAll(f, faceVertI) forAll(f, faceVertI)
@ -80,7 +76,7 @@ Foam::sampledPatch::interpolateField
if (!pointDone[pointI]) if (!pointDone[pointI])
{ {
label faceI = patchFaceLabels()[cutFaceI] + patch.start(); label faceI = patchFaceI + pp.start();
label cellI = own[faceI]; label cellI = own[faceI];
values[pointI] = interpolator.interpolate values[pointI] = interpolator.interpolate
@ -93,7 +89,6 @@ Foam::sampledPatch::interpolateField
} }
} }
} }
}
return tvalues; return tvalues;
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -56,15 +56,27 @@ Foam::sampledPatchInternalField::sampledPatchInternalField
) )
: :
sampledPatch(name, mesh, dict), sampledPatch(name, mesh, dict),
directMappedPatchBase mappers_(patchIDs().size())
{
const scalar distance = readScalar(dict.lookup("distance"));
forAll(patchIDs(), i)
{
label patchI = patchIDs()[i];
mappers_.set
( (
mesh.boundaryMesh()[sampledPatch::patchIndex()], i,
new directMappedPatchBase
(
mesh.boundaryMesh()[patchI],
mesh.name(), // sampleRegion mesh.name(), // sampleRegion
directMappedPatchBase::NEARESTCELL, // sampleMode directMappedPatchBase::NEARESTCELL, // sampleMode
word::null, // samplePatch word::null, // samplePatch
-readScalar(dict.lookup("distance")) -distance // sample inside my domain
) )
{} );
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
@ -167,7 +179,7 @@ Foam::tmp<Foam::tensorField> Foam::sampledPatchInternalField::interpolate
void Foam::sampledPatchInternalField::print(Ostream& os) const void Foam::sampledPatchInternalField::print(Ostream& os) const
{ {
os << "sampledPatchInternalField: " << name() << " :" os << "sampledPatchInternalField: " << name() << " :"
<< " patch:" << patchName() << " patches:" << patchNames()
<< " faces:" << faces().size() << " faces:" << faces().size()
<< " points:" << points().size(); << " points:" << points().size();
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -54,9 +54,13 @@ namespace Foam
class sampledPatchInternalField class sampledPatchInternalField
: :
public sampledPatch, public sampledPatch
public directMappedPatchBase
{ {
// Private data
//- Mapping engines
PtrList<directMappedPatchBase> mappers_;
// Private Member Functions // Private Member Functions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -36,20 +36,27 @@ Foam::sampledPatchInternalField::sampleField
const GeometricField<Type, fvPatchField, volMesh>& vField const GeometricField<Type, fvPatchField, volMesh>& vField
) const ) const
{ {
const mapDistribute& distMap = map();
// One value per face // One value per face
tmp<Field<Type> > tvalues(new Field<Type>(patchFaceLabels().size())); tmp<Field<Type> > tvalues(new Field<Type>(patchFaceLabels().size()));
Field<Type>& values = tvalues(); Field<Type>& values = tvalues();
if (patchIndex() != -1) forAll(patchStart(), i)
{ {
// Get patchface wise data by sampling internal field
Field<Type> interpVals = vField.internalField(); Field<Type> interpVals = vField.internalField();
distMap.distribute(interpVals); mappers_[i].map().distribute(interpVals);
forAll(patchFaceLabels(), elemI) // Store at correct position in values
label end =
(
i < patchStart().size()-1
? patchStart()[i+1]
: patchFaceLabels().size()
);
for (label triI = patchStart()[i]; triI < end; triI++)
{ {
values[elemI] = interpVals[patchFaceLabels()[elemI]]; values[triI] = interpVals[patchFaceLabels()[triI]];
} }
} }
@ -64,19 +71,24 @@ Foam::sampledPatchInternalField::interpolateField
const interpolation<Type>& interpolator const interpolation<Type>& interpolator
) const ) const
{ {
// One value per vertex label sz = 0;
forAll(patchIDs(), i)
{
sz += mesh().boundaryMesh()[patchIDs()[i]].size();
}
if (patchIndex() != -1) Field<Type> allPatchVals(sz);
sz = 0;
forAll(patchIDs(), i)
{ {
// See directMappedFixedValueFvPatchField // See directMappedFixedValueFvPatchField
const mapDistribute& distMap = map(); const mapDistribute& distMap = mappers_[i].map();
const polyPatch& pp = mesh().boundaryMesh()[patchIndex()];
// Send back sample points to processor that holds the cell. // Send back sample points to processor that holds the cell.
// Mark cells with point::max so we know which ones we need // Mark cells with point::max so we know which ones we need
// to interpolate (since expensive). // to interpolate (since expensive).
vectorField samples(samplePoints()); vectorField samples(mappers_[i].samplePoints());
distMap.reverseDistribute(mesh().nCells(), point::max, samples); distMap.reverseDistribute(mesh().nCells(), point::max, samples);
Field<Type> patchVals(mesh().nCells()); Field<Type> patchVals(mesh().nCells());
@ -96,18 +108,35 @@ Foam::sampledPatchInternalField::interpolateField
distMap.distribute(patchVals); distMap.distribute(patchVals);
// Now patchVals holds the interpolated data in patch face order. // Now patchVals holds the interpolated data in patch face order.
// Interpolate to points. Note: points are patch.localPoints() so // Collect.
// can use standard interpolation SubList<Type>(allPatchVals, patchVals.size(), sz).assign(patchVals);
sz += patchVals.size();
}
return PrimitivePatchInterpolation<primitivePatch> // Interpolate to points. Reconstruct the patch of all faces to aid
( // interpolation.
pp
).faceToPointInterpolate(patchVals); labelList meshFaceLabels(allPatchVals.size());
} sz = 0;
else forAll(patchIDs(), i)
{ {
return tmp<Field<Type> >(new Field<Type>(points().size())); const polyPatch& pp = mesh().boundaryMesh()[patchIDs()[i]];
forAll(pp, i)
{
meshFaceLabels[sz++] = pp.start()+i;
} }
}
indirectPrimitivePatch allPatches
(
IndirectList<face>(mesh().faces(), meshFaceLabels),
mesh().points()
);
return PrimitivePatchInterpolation<indirectPrimitivePatch>
(
allPatches
).faceToPointInterpolate(allPatchVals);
} }

View File

@ -124,7 +124,7 @@ functions
nearWall nearWall
{ {
type patchInternalField; type patchInternalField;
patchName lowerWall; patches ( lowerWall );
distance 1E-6; distance 1E-6;
interpolate true; interpolate true;
triangulate false; triangulate false;

View File

@ -124,7 +124,7 @@ functions
nearWall nearWall
{ {
type patchInternalField; type patchInternalField;
patchName lowerWall; patches ( lowerWall );
distance 1E-6; distance 1E-6;
interpolate true; interpolate true;
triangulate false; triangulate false;

View File

@ -89,7 +89,7 @@ functions
walls walls
{ {
type patch; type patch;
patchName walls; patches (walls);
triangulate false; triangulate false;
} }
); );

View File

@ -88,7 +88,7 @@ functions
walls walls
{ {
type patch; type patch;
patchName walls; patches (walls);
triangulate false; triangulate false;
} }
); );