Commit 7ad19bfb authored by mattijs's avatar mattijs
Browse files

ENH: GeometricField: support patch groups

parent 142142b1
......@@ -87,8 +87,6 @@ void Foam::vtkPV3Foam::reduceMemory()
}
int Foam::vtkPV3Foam::setTime(int nRequest, const double requestTimes[])
{
Time& runTime = dbPtr_();
......@@ -214,6 +212,7 @@ void Foam::vtkPV3Foam::updateMeshPartsStatus()
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::vtkPV3Foam::vtkPV3Foam
......@@ -378,7 +377,7 @@ void Foam::vtkPV3Foam::updateInfo()
// Update mesh parts list - add Lagrangian at the bottom
updateInfoInternalMesh(partSelection);
updateInfoPatches(partSelection);
updateInfoPatches(partSelection, enabledEntries);
updateInfoSets(partSelection);
updateInfoZones(partSelection);
updateInfoLagrangian(partSelection);
......
......@@ -347,7 +347,7 @@ class vtkPV3Foam
void updateInfoLagrangian(vtkDataArraySelection*);
//- Patch info
void updateInfoPatches(vtkDataArraySelection*);
void updateInfoPatches(vtkDataArraySelection*, stringList&);
//- Set info
void updateInfoSets(vtkDataArraySelection*);
......@@ -554,18 +554,6 @@ class vtkPV3Foam
const labelList& faceLabels
);
//- face set/zone field
template<class Type>
void convertFaceField
(
const GeometricField<Type, fvPatchField, volMesh>&,
vtkMultiBlockDataSet* output,
const arrayRange&,
const label datasetNo,
const fvMesh&,
const faceSet&
);
//- Lagrangian fields - all types
template<class Type>
void convertLagrangianFields
......
......@@ -110,79 +110,6 @@ void Foam::vtkPV3Foam::convertFaceField
}
template<class Type>
void Foam::vtkPV3Foam::convertFaceField
(
const GeometricField<Type, fvPatchField, volMesh>& tf,
vtkMultiBlockDataSet* output,
const arrayRange& range,
const label datasetNo,
const fvMesh& mesh,
const faceSet& fSet
)
{
const label nComp = pTraits<Type>::nComponents;
const label nInternalFaces = mesh.nInternalFaces();
const labelList& faceOwner = mesh.faceOwner();
const labelList& faceNeigh = mesh.faceNeighbour();
vtkFloatArray* cellData = vtkFloatArray::New();
cellData->SetNumberOfTuples(fSet.size());
cellData->SetNumberOfComponents(nComp);
cellData->Allocate(nComp*fSet.size());
cellData->SetName(tf.name().c_str());
if (debug)
{
Info<< "convert convertFaceField: "
<< tf.name()
<< " size = " << tf.size()
<< " nComp=" << nComp
<< " nTuples = " << fSet.size() << endl;
}
float vec[nComp];
// for interior faces: average owner/neighbour
// for boundary faces: owner
label faceI = 0;
forAllConstIter(faceSet, fSet, iter)
{
const label faceNo = iter.key();
if (faceNo < nInternalFaces)
{
Type t = 0.5*(tf[faceOwner[faceNo]] + tf[faceNeigh[faceNo]]);
for (direction d=0; d<nComp; ++d)
{
vec[d] = component(t, d);
}
}
else
{
const Type& t = tf[faceOwner[faceNo]];
for (direction d=0; d<nComp; ++d)
{
vec[d] = component(t, d);
}
}
vtkOpenFOAMTupleRemap<Type>(vec);
cellData->InsertTuple(faceI, vec);
++faceI;
}
vtkPolyData::SafeDownCast
(
GetDataSetFromBlock(output, range, datasetNo)
) ->GetCellData()
->AddArray(cellData);
cellData->Delete();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
......
......@@ -221,7 +221,8 @@ void Foam::vtkPV3Foam::updateInfoLagrangian
void Foam::vtkPV3Foam::updateInfoPatches
(
vtkDataArraySelection* arraySelection
vtkDataArraySelection* arraySelection,
stringList& enabledEntries
)
{
if (debug)
......@@ -230,12 +231,63 @@ void Foam::vtkPV3Foam::updateInfoPatches
<< " [meshPtr=" << (meshPtr_ ? "set" : "NULL") << "]" << endl;
}
HashSet<string> enabledEntriesSet(enabledEntries);
arrayRangePatches_.reset(arraySelection->GetNumberOfArrays());
int nPatches = 0;
if (meshPtr_)
{
const polyBoundaryMesh& patches = meshPtr_->boundaryMesh();
const HashTable<labelList, word>& groups = patches.groupPatchIDs();
const wordList allPatchNames = patches.names();
// Add patch groups
// ~~~~~~~~~~~~~~~~
for
(
HashTable<labelList, word>::const_iterator iter = groups.begin();
iter != groups.end();
++iter
)
{
const word& groupName = iter.key();
const labelList& patchIDs = iter();
label nFaces = 0;
forAll(patchIDs, i)
{
nFaces += patches[patchIDs[i]].size();
}
// Valid patch if nFace > 0 - add patch to GUI list
if (nFaces)
{
string vtkGrpName = groupName + " - group";
arraySelection->AddArray(vtkGrpName.c_str());
++nPatches;
if (enabledEntriesSet.found(vtkGrpName))
{
forAll(patchIDs, i)
{
const polyPatch& pp = patches[patchIDs[i]];
string vtkPatchName = pp.name() + " - patch";
enabledEntriesSet.insert(vtkPatchName);
}
enabledEntriesSet.erase(vtkGrpName);
}
}
}
// Add patches
// ~~~~~~~~~~~
forAll(patches, patchI)
{
const polyPatch& pp = patches[patchI];
......@@ -277,20 +329,101 @@ void Foam::vtkPV3Foam::updateInfoPatches
{
polyBoundaryMeshEntries patchEntries(ioObj);
// Add (non-zero) patches to the list of mesh parts
forAll(patchEntries, entryI)
// Read patches and determine sizes
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wordList names(patchEntries.size());
labelList sizes(patchEntries.size());
forAll(patchEntries, patchI)
{
label nFaces
(
readLabel(patchEntries[entryI].dict().lookup("nFaces"))
);
const dictionary& patchDict = patchEntries[patchI].dict();
sizes[patchI] = readLabel(patchDict.lookup("nFaces"));
names[patchI] = patchEntries[patchI].keyword();
}
// Add (non-zero) patch groups to the list of mesh parts
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HashTable<labelList, word> groups(patchEntries.size());
forAll(patchEntries, patchI)
{
const dictionary& patchDict = patchEntries[patchI].dict();
wordList groupNames;
patchDict.readIfPresent("inGroups", groupNames);
forAll(groupNames, groupI)
{
HashTable<labelList, word>::iterator iter = groups.find
(
groupNames[groupI]
);
if (iter != groups.end())
{
iter().append(patchI);
}
else
{
groups.insert(groupNames[groupI], labelList(1, patchI));
}
}
}
for
(
HashTable<labelList, word>::const_iterator iter =
groups.begin();
iter != groups.end();
++iter
)
{
const word& groupName = iter.key();
const labelList& patchIDs = iter();
label nFaces = 0;
forAll(patchIDs, i)
{
nFaces += sizes[patchIDs[i]];
}
// Valid patch if nFace > 0 - add patch to GUI list
if (nFaces)
{
string vtkGrpName = groupName + " - group";
arraySelection->AddArray(vtkGrpName.c_str());
++nPatches;
if (enabledEntriesSet.found(vtkGrpName))
{
forAll(patchIDs, i)
{
string vtkPatchName =
names[patchIDs[i]] + " - patch";
enabledEntriesSet.insert(vtkPatchName);
}
enabledEntriesSet.erase(vtkGrpName);
}
}
}
// Add (non-zero) patches to the list of mesh parts
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
forAll(names, patchI)
{
// Valid patch if nFace > 0 - add patch to GUI list
if (sizes[patchI])
{
arraySelection->AddArray
(
(patchEntries[entryI].keyword() + " - patch").c_str()
(names[patchI] + " - patch").c_str()
);
++nPatches;
......@@ -300,6 +433,9 @@ void Foam::vtkPV3Foam::updateInfoPatches
}
arrayRangePatches_ += nPatches;
// Update enabled entries in case of group selection
enabledEntries = enabledEntriesSet.toc();
if (debug)
{
// just for debug info
......
......@@ -271,7 +271,7 @@ void Foam::vtkPV3Foam::convertVolFields
arrayRangeFaceSets_,
datasetNo,
mesh,
fSet
fSet.toc()
);
// TODO: points
......
......@@ -248,15 +248,81 @@ GeometricBoundaryField
<< endl;
}
forAll(bmesh_, patchi)
// Check for groups first. (using non-wild card entries of dictionaries)
forAllConstIter(dictionary, dict, iter)
{
if (bmesh_[patchi].type() != emptyPolyPatch::typeName)
if (iter().isDict())
{
if
const labelList patchIDs = bmesh_.findIndices
(
bmesh_[patchi].type() == cyclicPolyPatch::typeName
&& !dict.found(bmesh_[patchi].name())
)
iter().keyword(),
true
);
forAll(patchIDs, i)
{
label patchi = patchIDs[i];
this->set
(
patchi,
PatchField<Type>::New
(
bmesh_[patchi],
field,
iter().dict()
)
);
}
}
}
// Check for explicit patch overrides
forAll(bmesh_, patchi)
{
if (bmesh_[patchi].type() == emptyPolyPatch::typeName)
{
if (!this->set(patchi))
{
this->set
(
patchi,
PatchField<Type>::New
(
emptyPolyPatch::typeName,
bmesh_[patchi],
field
)
);
}
}
else
{
bool found = dict.found(bmesh_[patchi].name());
if (found)
{
this->set
(
patchi,
PatchField<Type>::New
(
bmesh_[patchi],
field,
dict.subDict(bmesh_[patchi].name())
)
);
}
}
}
// Check for any unset patches
forAll(bmesh_, patchi)
{
if (!this->set(patchi))
{
if (bmesh_[patchi].type() == cyclicPolyPatch::typeName)
{
FatalIOErrorIn
(
......@@ -274,30 +340,21 @@ GeometricBoundaryField
<< "Run foamUpgradeCyclics to convert mesh and fields"
<< " to split cyclics." << exit(FatalIOError);
}
this->set
(
patchi,
PatchField<Type>::New
(
bmesh_[patchi],
field,
dict.subDict(bmesh_[patchi].name())
)
);
}
else
{
this->set
(
patchi,
PatchField<Type>::New
else
{
FatalIOErrorIn
(
emptyPolyPatch::typeName,
bmesh_[patchi],
field
)
);
"GeometricField<Type, PatchField, GeoMesh>::\n"
"GeometricBoundaryField::GeometricBoundaryField\n"
"(\n"
" const BoundaryMesh&,\n"
" const DimensionedField<Type, GeoMesh>&,\n"
" const dictionary&\n"
")",
dict
) << "Cannot find patchField entry for "
<< bmesh_[patchi].name() << exit(FatalIOError);
}
}
}
}
......
......@@ -32,12 +32,14 @@ Foam::patchIdentifier::patchIdentifier
(
const word& name,
const label index,
const word& physicalType
const word& physicalType,
const wordList& inGroups
)
:
name_(name),
index_(index),
physicalType_(physicalType)
physicalType_(physicalType),
inGroups_(inGroups)
{}
......@@ -52,6 +54,7 @@ Foam::patchIdentifier::patchIdentifier
index_(index)
{
dict.readIfPresent("physicalType", physicalType_);
dict.readIfPresent("inGroups", inGroups_);
}
......@@ -63,7 +66,8 @@ Foam::patchIdentifier::patchIdentifier
:
name_(p.name_),
index_(index),
physicalType_(p.physicalType_)
physicalType_(p.physicalType_),
inGroups_(p.inGroups_)
{}
......@@ -82,6 +86,11 @@ void Foam::patchIdentifier::write(Ostream& os) const
os.writeKeyword("physicalType") << physicalType_
<< token::END_STATEMENT << nl;
}
if (inGroups_.size())
{
os.writeKeyword("inGroups") << inGroups_
<< token::END_STATEMENT << nl;
}
}
......
......@@ -35,7 +35,7 @@ SourceFiles
#ifndef patchIdentifier_H
#define patchIdentifier_H
#include "word.H"
#include "wordList.H"
#include "label.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -68,6 +68,8 @@ class patchIdentifier
//- Optional physical type
mutable word physicalType_;
//- Optional groups patch belongs to
wordList inGroups_;
public:
......@@ -78,7 +80,8 @@ public:
(
const word& name,
const label index,
const word& physicalType = word::null
const word& physicalType = word::null,
const wordList& inGroups = wordList()
);
//- Construct from dictionary
......@@ -139,6 +142,19 @@ public:
return index_;
}
//- Return the optional groups patch belongs to
const wordList& inGroups() const
{
return inGroups_;
}
//- Return the optional groups patch belongs to for modification
wordList& inGroups()
{
return inGroups_;
}
//- Write patchIdentifier as a dictionary
void write(Ostream&) const;
......
......@@ -58,6 +58,16 @@ Foam::pointBoundaryMesh::pointBoundaryMesh
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::labelList Foam::pointBoundaryMesh::findIndices
(
const keyType& key,
const bool usePatchGroups
) const
{
return mesh()().boundaryMesh().findIndices(key, usePatchGroups);
}
void Foam::pointBoundaryMesh::calcGeometry()
{
PstreamBuffers pBufs(Pstream::defaultCommsType);
......