From 8939a55653c636358b22e5ed58acd493560546d7 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Mon, 5 Oct 2020 12:30:41 +0200 Subject: [PATCH] ENH: relocate blockMesh polyMesh generation into library (for code reuse) STYLE: adjust blockMesh advanced/non-advanced options - make -merge-points "non-advanced" (for better exposure) - make -write-obj "advanced" (-write-vtk is preferred) --- .../mesh/generation/blockMesh/addCellZones.H | 88 +----------- .../mesh/generation/blockMesh/blockMesh.C | 73 +++------- .../blockMesh/handleCyclicPatches.H | 22 +++ .../generation/blockMesh/mergePatchPairs.H | 42 +++--- src/mesh/blockMesh/blockMesh/blockMesh.C | 12 +- src/mesh/blockMesh/blockMesh/blockMesh.H | 36 +++-- .../blockMesh/blockMesh/blockMeshCreate.C | 128 +++++++++++++++++- 7 files changed, 225 insertions(+), 176 deletions(-) create mode 100644 applications/utilities/mesh/generation/blockMesh/handleCyclicPatches.H diff --git a/applications/utilities/mesh/generation/blockMesh/addCellZones.H b/applications/utilities/mesh/generation/blockMesh/addCellZones.H index eca57f2ed4a..7cec1b4541d 100644 --- a/applications/utilities/mesh/generation/blockMesh/addCellZones.H +++ b/applications/utilities/mesh/generation/blockMesh/addCellZones.H @@ -1,87 +1 @@ -// Set any cellZones -// Note cell labelling unaffected by previous mergePatchPairs - -{ - const label nZones = blocks.numZonedBlocks(); - if (nZones) - { - Info<< nl << "Adding cell zones" << endl; - - // Map from zoneName to cellZone index - HashTable<label> zoneMap(nZones); - - // Cells per zone. - List<DynamicList<label>> zoneCells(nZones); - - // Running cell counter - label celli = 0; - - // Largest zone so far - label freeZoneI = 0; - - for (const block& b : blocks) - { - const word& zoneName = b.zoneName(); - const label nCellsInBlock = b.cells().size(); - - if (zoneName.size()) - { - const auto iter = zoneMap.cfind(zoneName); - - label zonei; - - if (iter.found()) - { - zonei = *iter; - } - else - { - zonei = freeZoneI++; - - Info<< " " << zonei << '\t' << zoneName << endl; - - zoneMap.insert(zoneName, zonei); - } - - - // Fill with cell ids - - zoneCells[zonei].reserve - ( - zoneCells[zonei].size() + nCellsInBlock - ); - - const label endOfFill = celli + nCellsInBlock; - - for (; celli < endOfFill; ++celli) - { - zoneCells[zonei].append(celli); - } - } - else - { - celli += nCellsInBlock; - } - } - - List<cellZone*> cz(zoneMap.size()); - forAllConstIters(zoneMap, iter) - { - const word& zoneName = iter.key(); - const label zonei = iter.val(); - - cz[zonei] = new cellZone - ( - zoneName, - zoneCells[zonei].shrink(), - zonei, - mesh.cellZones() - ); - } - - mesh.pointZones().resize(0); - mesh.faceZones().resize(0); - mesh.cellZones().resize(0); - mesh.addZones(List<pointZone*>(), List<faceZone*>(), cz); - } -} +#warning File removed - left for old dependency check only diff --git a/applications/utilities/mesh/generation/blockMesh/blockMesh.C b/applications/utilities/mesh/generation/blockMesh/blockMesh.C index 0eec9f01b8e..b510d911705 100644 --- a/applications/utilities/mesh/generation/blockMesh/blockMesh.C +++ b/applications/utilities/mesh/generation/blockMesh/blockMesh.C @@ -77,7 +77,6 @@ Usage #include "foamVtkInternalMeshWriter.H" #include "attachPolyTopoChanger.H" #include "polyTopoChange.H" -#include "emptyPolyPatch.H" #include "cyclicPolyPatch.H" #include "cellSet.H" @@ -85,7 +84,7 @@ Usage #include "OSspecific.H" #include "OFstream.H" -#include "Pair.H" +#include "wordPair.H" #include "slidingInterface.H" using namespace Foam; @@ -122,7 +121,8 @@ int main(int argc, char *argv[]) argList::addBoolOption ( "write-obj", - "Write block edges and centres as obj files and exit" + "Write block edges and centres as obj files and exit", + true // (old) mark as advanced option. -write-vtk is preferred ); argList::addOptionCompat("write-obj", {"blockTopology", 1912}); @@ -135,9 +135,9 @@ int main(int argc, char *argv[]) argList::addBoolOption ( "merge-points", - "Geometric (point) merging instead of topological merging " - "(slower, fails with high-aspect cells. default for 1912 and earlier)", - true // mark as an advanced option + "Geometric point merging instead of topological merging" + " [default for 1912 and earlier]." + // NOTE: " Slower, fails with high-aspect cells." ); argList::addBoolOption ( @@ -164,6 +164,9 @@ int main(int argc, char *argv[]) // Remove old files, unless disabled const bool removeOldFiles = !args.found("noClean"); + // Write cellSets + const bool writeCellSets = args.found("sets"); + // Default merge (topology), unless otherwise specified blockMesh::mergeStrategy strategy(blockMesh::DEFAULT_MERGE); @@ -329,56 +332,22 @@ int main(int argc, char *argv[]) } - Info<< nl << "Creating polyMesh from blockMesh" << endl; + // Ensure we get information messages, even if turned off in dictionary + blocks.verbose(true); - polyMesh mesh - ( - IOobject + autoPtr<polyMesh> meshPtr = + blocks.mesh ( - regionName, - meshInstance, - runTime - ), - pointField(blocks.points()), // Copy, could we re-use space? - blocks.cells(), - blocks.patches(), - blocks.patchNames(), - blocks.patchDicts(), - "defaultFaces", // Default patch name - emptyPolyPatch::typeName // Default patch type - ); + IOobject(regionName, meshInstance, runTime) + ); + polyMesh& mesh = *meshPtr; - // Handle merging of patch pairs. Dictionary entry "mergePatchPairs" + // Merge patch pairs (dictionary entry "mergePatchPairs") #include "mergePatchPairs.H" - // Set any cellZones - #include "addCellZones.H" - - - // Detect any cyclic patches and force re-ordering of the faces - { - bool hasCyclic = false; - for (const polyPatch& pp : mesh.boundaryMesh()) - { - if (isA<cyclicPolyPatch>(pp)) - { - hasCyclic = true; - break; - } - } - - if (hasCyclic) - { - Info<< nl << "Detected cyclic patches; ordering boundary faces" - << endl; - const word oldInstance = mesh.instance(); - polyTopoChange meshMod(mesh); - meshMod.changeMesh(mesh, false); - mesh.setInstance(oldInstance); - } - } - + // Handle cyclic patches + #include "handleCyclicPatches.H" // Set the precision of the points data to 10 IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision())); @@ -386,7 +355,7 @@ int main(int argc, char *argv[]) Info<< nl << "Writing polyMesh with " << mesh.cellZones().size() << " cellZones"; - if (args.found("sets") && !mesh.cellZones().empty()) + if (writeCellSets && !mesh.cellZones().empty()) { Info<< " (written as cellSets too)"; } @@ -400,7 +369,7 @@ int main(int argc, char *argv[]) << exit(FatalError); } - if (args.found("sets")) + if (writeCellSets) { for (const cellZone& cz : mesh.cellZones()) { diff --git a/applications/utilities/mesh/generation/blockMesh/handleCyclicPatches.H b/applications/utilities/mesh/generation/blockMesh/handleCyclicPatches.H new file mode 100644 index 00000000000..eb79d02de20 --- /dev/null +++ b/applications/utilities/mesh/generation/blockMesh/handleCyclicPatches.H @@ -0,0 +1,22 @@ +// Detect any cyclic patches and force re-ordering of the faces +{ + bool hasCyclic = false; + for (const polyPatch& pp : mesh.boundaryMesh()) + { + if (isA<cyclicPolyPatch>(pp)) + { + hasCyclic = true; + break; + } + } + + if (hasCyclic) + { + Info<< nl << "Detected cyclic patches; ordering boundary faces" << endl; + + const word oldInstance = mesh.instance(); + polyTopoChange meshMod(mesh); + meshMod.changeMesh(mesh, false); + mesh.setInstance(oldInstance); + } +} diff --git a/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H b/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H index 2c94bcc0fa6..be551d01f60 100644 --- a/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H +++ b/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H @@ -1,6 +1,6 @@ // Handle merging of patch pairs { - List<Pair<word>> mergePatchPairs; + wordPairList mergePatchPairs; // Read in a list of dictionaries for the merge patch pairs if @@ -14,19 +14,19 @@ // Create and add point and face zones and mesh modifiers List<pointZone*> pz(mergePatchPairs.size()); List<faceZone*> fz(3*mergePatchPairs.size()); - List<cellZone*> cz(0); + List<cellZone*> cz; - forAll(mergePatchPairs, pairI) + forAll(mergePatchPairs, pairi) { const word mergeName ( - mergePatchPairs[pairI].first() - + mergePatchPairs[pairI].second() - + name(pairI) + mergePatchPairs[pairi].first() + + mergePatchPairs[pairi].second() + + name(pairi) ); // An empty zone for cut points - pz[pairI] = new pointZone + pz[pairi] = new pointZone ( mergeName + "CutPointZone", 0, @@ -34,11 +34,11 @@ ); // Master patch - const word masterPatchName(mergePatchPairs[pairI].first()); + const word masterPatchName(mergePatchPairs[pairi].first()); const polyPatch& masterPatch = mesh.boundaryMesh()[masterPatchName]; - fz[3*pairI] = new faceZone + fz[3*pairi] = new faceZone ( mergeName + "MasterZone", identity(masterPatch.size(), masterPatch.start()), @@ -48,11 +48,11 @@ ); // Slave patch - const word slavePatchName(mergePatchPairs[pairI].second()); + const word slavePatchName(mergePatchPairs[pairi].second()); const polyPatch& slavePatch = mesh.boundaryMesh()[slavePatchName]; - fz[3*pairI + 1] = new faceZone + fz[3*pairi + 1] = new faceZone ( mergeName + "SlaveZone", identity(slavePatch.size(), slavePatch.start()), @@ -62,7 +62,7 @@ ); // An empty zone for cut faces - fz[3*pairI + 2] = new faceZone + fz[3*pairi + 2] = new faceZone ( mergeName + "CutFaceZone", 2, @@ -78,30 +78,30 @@ attachPolyTopoChanger polyMeshAttacher(mesh); polyMeshAttacher.setSize(mergePatchPairs.size()); - forAll(mergePatchPairs, pairI) + forAll(mergePatchPairs, pairi) { const word mergeName ( - mergePatchPairs[pairI].first() - + mergePatchPairs[pairI].second() - + name(pairI) + mergePatchPairs[pairi].first() + + mergePatchPairs[pairi].second() + + name(pairi) ); // Add the sliding interface mesh modifier polyMeshAttacher.set ( - pairI, + pairi, new slidingInterface ( - "couple" + name(pairI), - pairI, + "couple" + name(pairi), + pairi, polyMeshAttacher, mergeName + "MasterZone", mergeName + "SlaveZone", mergeName + "CutPointZone", mergeName + "CutFaceZone", - mergePatchPairs[pairI].first(), - mergePatchPairs[pairI].second(), + mergePatchPairs[pairi].first(), + mergePatchPairs[pairi].second(), slidingInterface::INTEGRAL, // always integral false, intersection::VISIBLE diff --git a/src/mesh/blockMesh/blockMesh/blockMesh.C b/src/mesh/blockMesh/blockMesh/blockMesh.C index 3df87de8d24..04db49d80c6 100644 --- a/src/mesh/blockMesh/blockMesh/blockMesh.C +++ b/src/mesh/blockMesh/blockMesh/blockMesh.C @@ -109,15 +109,23 @@ Foam::blockMesh::blockMesh // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -bool Foam::blockMesh::valid() const +bool Foam::blockMesh::valid() const noexcept { return bool(topologyPtr_); } -void Foam::blockMesh::verbose(const bool on) +bool Foam::blockMesh::verbose() const noexcept { + return verboseOutput; +} + + +bool Foam::blockMesh::verbose(const bool on) noexcept +{ + bool old(verboseOutput); verboseOutput = on; + return old; } diff --git a/src/mesh/blockMesh/blockMesh/blockMesh.H b/src/mesh/blockMesh/blockMesh/blockMesh.H index 4227b3de067..d08a4755859 100644 --- a/src/mesh/blockMesh/blockMesh/blockMesh.H +++ b/src/mesh/blockMesh/blockMesh/blockMesh.H @@ -226,10 +226,10 @@ public: //- Construct from IOdictionary for given region // Default is topological merging. - blockMesh + explicit blockMesh ( const IOdictionary& dict, - const word& regionName, + const word& regionName = polyMesh::defaultRegion, mergeStrategy strategy = mergeStrategy::DEFAULT_MERGE ); @@ -255,10 +255,10 @@ public: } //- True if the blockMesh topology exists - bool valid() const; + bool valid() const noexcept; - //- Reference to point field defining the blockMesh - // these points have not been scaled by scaleFactor + //- Reference to point field defining the blockMesh. + // These points are \b not scaled by scaleFactor const pointField& vertices() const; //- Return the blockMesh topology as a polyMesh @@ -279,8 +279,8 @@ public: //- The scaling factor used to convert to metres scalar scaleFactor() const; - //- The points for the entire mesh - // these points have been scaled by scaleFactor + //- The points for the entire mesh. + // These points \b are scaled by scaleFactor const pointField& points() const; //- Return cell shapes list @@ -299,16 +299,26 @@ public: label numZonedBlocks() const; - // Edit + // Verbosity - //- Enable/disable verbose information about the progress - void verbose(const bool on=true); + //- Verbose information? + bool verbose() const noexcept; + //- Enable/disable verbose information about the progress + // \return old value + bool verbose(const bool on) noexcept; - // Write - //- Writes edges of blockMesh in OBJ format. - void writeTopology(Ostream&) const; + // Mesh Generation + + //- Create polyMesh, with cell zones + autoPtr<polyMesh> mesh(const IOobject& io) const; + + + // Write + + //- Writes edges of blockMesh in OBJ format. + void writeTopology(Ostream& os) const; }; diff --git a/src/mesh/blockMesh/blockMesh/blockMeshCreate.C b/src/mesh/blockMesh/blockMesh/blockMeshCreate.C index 4e8dad0cc6f..8d93b69b872 100644 --- a/src/mesh/blockMesh/blockMesh/blockMeshCreate.C +++ b/src/mesh/blockMesh/blockMesh/blockMeshCreate.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,6 +28,7 @@ License #include "blockMesh.H" #include "cellModel.H" +#include "emptyPolyPatch.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -270,4 +271,129 @@ void Foam::blockMesh::createPatches() const } +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::autoPtr<Foam::polyMesh> +Foam::blockMesh::mesh(const IOobject& io) const +{ + const blockMesh& blkMesh = *this; + + if (verboseOutput) + { + Info<< nl << "Creating polyMesh from blockMesh" << endl; + } + + auto meshPtr = autoPtr<polyMesh>::New + ( + io, + pointField(blkMesh.points()), // Copy, could we re-use space? + blkMesh.cells(), + blkMesh.patches(), + blkMesh.patchNames(), + blkMesh.patchDicts(), + "defaultFaces", // Default patch name + emptyPolyPatch::typeName // Default patch type + ); + + + // Set any cellZones + const label nZones = blkMesh.numZonedBlocks(); + + if (nZones) + { + polyMesh& pmesh = *meshPtr; + + if (verboseOutput) + { + Info<< "Adding cell zones" << endl; + } + + // Map from zoneName to cellZone index + HashTable<label> zoneMap(2*nZones); + + // Cells per zone + List<DynamicList<label>> zoneCells(nZones); + + // Running cell counter + label celli = 0; + + // Largest zone so far + label freeZonei = 0; + + for (const block& b : blkMesh) + { + const word& zoneName = b.zoneName(); + const label nCellsInBlock = b.cells().size(); + + if (zoneName.size()) + { + const auto iter = zoneMap.cfind(zoneName); + + label zonei = freeZonei; + + if (iter.found()) + { + zonei = *iter; + } + else + { + zoneMap.insert(zoneName, zonei); + ++freeZonei; + + if (verboseOutput) + { + Info<< " " << zonei << '\t' << zoneName << endl; + } + } + + + // Fill with cell ids + + zoneCells[zonei].reserve + ( + zoneCells[zonei].size() + nCellsInBlock + ); + + const label endOfFill = celli + nCellsInBlock; + + for (; celli < endOfFill; ++celli) + { + zoneCells[zonei].append(celli); + } + } + else + { + celli += nCellsInBlock; + } + } + + List<cellZone*> cz(zoneMap.size()); + forAllConstIters(zoneMap, iter) + { + const word& zoneName = iter.key(); + const label zonei = iter.val(); + + cz[zonei] = new cellZone + ( + zoneName, + zoneCells[zonei].shrink(), + zonei, + pmesh.cellZones() + ); + } + + pmesh.pointZones().resize(0); + pmesh.faceZones().resize(0); + pmesh.cellZones().resize(0); + pmesh.addZones(List<pointZone*>(), List<faceZone*>(), cz); + } + + + // Merge patch pairs, cyclic must be done elsewhere + // - requires libdynamicMesh + + return meshPtr; +} + + // ************************************************************************* // -- GitLab