diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C index 11ecb12081..5a2e599a64 100644 --- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C +++ b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C @@ -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); diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H index 7d9a481b49..b4d031b7ec 100644 --- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H +++ b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H @@ -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 - void convertFaceField - ( - const GeometricField&, - vtkMultiBlockDataSet* output, - const arrayRange&, - const label datasetNo, - const fvMesh&, - const faceSet& - ); - //- Lagrangian fields - all types template void convertLagrangianFields diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFaceField.H b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFaceField.H index 030c9aca05..b37255a8f1 100644 --- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFaceField.H +++ b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFaceField.H @@ -110,79 +110,6 @@ void Foam::vtkPV3Foam::convertFaceField } -template -void Foam::vtkPV3Foam::convertFaceField -( - const GeometricField& tf, - vtkMultiBlockDataSet* output, - const arrayRange& range, - const label datasetNo, - const fvMesh& mesh, - const faceSet& fSet -) -{ - const label nComp = pTraits::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(vec); - - cellData->InsertTuple(faceI, vec); - ++faceI; - } - - - vtkPolyData::SafeDownCast - ( - GetDataSetFromBlock(output, range, datasetNo) - ) ->GetCellData() - ->AddArray(cellData); - - cellData->Delete(); -} - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfo.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfo.C index deff6377ad..642e5dbaae 100644 --- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfo.C +++ b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfo.C @@ -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 enabledEntriesSet(enabledEntries); + arrayRangePatches_.reset(arraySelection->GetNumberOfArrays()); int nPatches = 0; if (meshPtr_) { const polyBoundaryMesh& patches = meshPtr_->boundaryMesh(); + const HashTable& groups = patches.groupPatchIDs(); + + const wordList allPatchNames = patches.names(); + + // Add patch groups + // ~~~~~~~~~~~~~~~~ + + for + ( + HashTable::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 groups(patchEntries.size()); + + forAll(patchEntries, patchI) + { + const dictionary& patchDict = patchEntries[patchI].dict(); + + wordList groupNames; + patchDict.readIfPresent("inGroups", groupNames); + forAll(groupNames, groupI) + { + HashTable::iterator iter = groups.find + ( + groupNames[groupI] + ); + if (iter != groups.end()) + { + iter().append(patchI); + } + else + { + groups.insert(groupNames[groupI], labelList(1, patchI)); + } + } + } + + for + ( + HashTable::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 diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamVolFields.H b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamVolFields.H index a057afb511..57e6931c12 100644 --- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamVolFields.H +++ b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamVolFields.H @@ -271,7 +271,7 @@ void Foam::vtkPV3Foam::convertVolFields arrayRangeFaceSets_, datasetNo, mesh, - fSet + fSet.toc() ); // TODO: points diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C index 6b8d4587b0..e80da7c9ca 100644 --- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C +++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C @@ -248,15 +248,81 @@ GeometricBoundaryField << endl; } + + // Check for groups first. (using non-wild card entries of dictionaries) + forAllConstIter(dictionary, dict, iter) + { + if (iter().isDict()) + { + const labelList patchIDs = bmesh_.findIndices + ( + iter().keyword(), + true + ); + + forAll(patchIDs, i) + { + label patchi = patchIDs[i]; + this->set + ( + patchi, + PatchField::New + ( + bmesh_[patchi], + field, + iter().dict() + ) + ); + } + } + } + + // Check for explicit patch overrides forAll(bmesh_, patchi) { - if (bmesh_[patchi].type() != emptyPolyPatch::typeName) + if (bmesh_[patchi].type() == emptyPolyPatch::typeName) { - if - ( - bmesh_[patchi].type() == cyclicPolyPatch::typeName - && !dict.found(bmesh_[patchi].name()) - ) + if (!this->set(patchi)) + { + this->set + ( + patchi, + PatchField::New + ( + emptyPolyPatch::typeName, + bmesh_[patchi], + field + ) + ); + } + } + else + { + bool found = dict.found(bmesh_[patchi].name()); + + if (found) + { + this->set + ( + patchi, + PatchField::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::New + else + { + FatalIOErrorIn ( - bmesh_[patchi], - field, - dict.subDict(bmesh_[patchi].name()) - ) - ); - } - else - { - this->set - ( - patchi, - PatchField::New - ( - emptyPolyPatch::typeName, - bmesh_[patchi], - field - ) - ); + "GeometricField::\n" + "GeometricBoundaryField::GeometricBoundaryField\n" + "(\n" + " const BoundaryMesh&,\n" + " const DimensionedField&,\n" + " const dictionary&\n" + ")", + dict + ) << "Cannot find patchField entry for " + << bmesh_[patchi].name() << exit(FatalIOError); + } } } } diff --git a/src/OpenFOAM/meshes/Identifiers/patch/patchIdentifier.C b/src/OpenFOAM/meshes/Identifiers/patch/patchIdentifier.C index f5baa164d0..6137986165 100644 --- a/src/OpenFOAM/meshes/Identifiers/patch/patchIdentifier.C +++ b/src/OpenFOAM/meshes/Identifiers/patch/patchIdentifier.C @@ -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; + } } diff --git a/src/OpenFOAM/meshes/Identifiers/patch/patchIdentifier.H b/src/OpenFOAM/meshes/Identifiers/patch/patchIdentifier.H index bd355f1756..cb7d60b7b5 100644 --- a/src/OpenFOAM/meshes/Identifiers/patch/patchIdentifier.H +++ b/src/OpenFOAM/meshes/Identifiers/patch/patchIdentifier.H @@ -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; diff --git a/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.C b/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.C index 113a9719a0..c8ec20fff2 100644 --- a/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.C +++ b/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.C @@ -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); diff --git a/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.H b/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.H index 0e6e2b9016..afbc52c93f 100644 --- a/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.H +++ b/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.H @@ -96,6 +96,9 @@ public: return mesh_; } + //- Find patch indices given a name + labelList findIndices(const keyType&, const bool useGroups) const; + //- Correct polyBoundaryMesh after moving points void movePoints(const pointField&); diff --git a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C index 94a1597d96..ab13b34444 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C +++ b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C @@ -151,6 +151,7 @@ void Foam::polyBoundaryMesh::clearAddressing() { neighbourEdgesPtr_.clear(); patchIDPtr_.clear(); + groupPatchIDsPtr_.clear(); forAll(*this, patchI) { @@ -369,6 +370,54 @@ const Foam::labelList& Foam::polyBoundaryMesh::patchID() const } +const Foam::HashTable& +Foam::polyBoundaryMesh::groupPatchIDs() const +{ + if (!groupPatchIDsPtr_.valid()) + { + groupPatchIDsPtr_.reset(new HashTable(10)); + HashTable& groupPatchIDs = groupPatchIDsPtr_(); + + const polyBoundaryMesh& bm = *this; + + forAll(bm, patchI) + { + const wordList& groups = bm[patchI].inGroups(); + + forAll(groups, i) + { + const word& name = groups[i]; + + if (findPatchID(name) != -1) + { + WarningIn("polyBoundaryMesh::groupPatchIDs() const") + << "Patch " << bm[patchI].name() + << " specifies a group " << name + << " which is also a patch name." + << " This might give problems later on." << endl; + } + + + HashTable::iterator iter = groupPatchIDs.find + ( + name + ); + + if (iter != groupPatchIDs.end()) + { + iter().append(patchI); + } + else + { + groupPatchIDs.insert(name, labelList(1, patchI)); + } + } + } + } + return groupPatchIDsPtr_(); +} + + Foam::wordList Foam::polyBoundaryMesh::names() const { const polyPatchList& patches = *this; @@ -414,28 +463,74 @@ Foam::wordList Foam::polyBoundaryMesh::physicalTypes() const } -Foam::labelList Foam::polyBoundaryMesh::findIndices(const keyType& key) const +Foam::labelList Foam::polyBoundaryMesh::findIndices +( + const keyType& key, + const bool usePatchGroups +) const { - labelList indices; + DynamicList