From 15cad22d8c06b17cb620020198635d389ac768ca Mon Sep 17 00:00:00 2001 From: mattijs Date: Wed, 9 Jul 2008 00:21:36 +0100 Subject: [PATCH] split autoHexMeshDriver; updated header --- .../generation/snappyHexMesh/snappyHexMesh.C | 342 +- .../snappyHexMesh/snappyHexMeshDict | 50 +- src/autoMesh/Make/files | 8 +- .../autoHexMeshDriver/autoHexMeshDriver.C | 1784 ++-------- .../autoHexMeshDriver/autoHexMeshDriver.H | 651 +--- .../autoHexMeshDriver/autoLayerDriver.C | 3128 +++++++++++++++++ .../autoHexMeshDriver/autoLayerDriver.H | 562 +++ .../autoHexMeshDriver/autoLayerDriverShrink.C | 1159 ++++++ .../autoLayerDriverTemplates.C | 76 + .../autoHexMeshDriver/autoRefineDriver.C | 776 ++++ .../autoHexMeshDriver/autoRefineDriver.H | 179 + .../autoHexMeshDriver/autoSnapDriver.C | 1385 ++++++++ .../autoHexMeshDriver/autoSnapDriver.H | 236 ++ .../layerParameters/layerParameters.C | 118 +- .../layerParameters/layerParameters.H | 19 +- .../meshRefinement/meshRefinement.C | 236 +- .../meshRefinement/meshRefinement.H | 34 +- .../refinementSurfaces/refinementSurfaces.H | 9 +- .../searchableSurface/searchableBox.C | 2 +- .../searchableSurface/searchableBox.H | 2 +- .../searchableSurface/searchableSphere.C | 2 +- .../searchableSurface/searchableSphere.H | 2 +- .../searchableSurface/searchableSurface.C | 2 +- .../searchableSurface/searchableSurface.H | 2 +- .../searchableSurface/searchableSurfaces.C | 2 +- .../searchableSurface/searchableSurfaces.H | 2 +- .../searchableSurfacesQueries.C | 2 +- .../searchableSurfacesQueries.H | 2 +- .../searchableSurface/triSurfaceMesh.C | 2 +- .../searchableSurface/triSurfaceMesh.H | 2 +- 30 files changed, 8501 insertions(+), 2275 deletions(-) create mode 100644 src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C create mode 100644 src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H create mode 100644 src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C create mode 100644 src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverTemplates.C create mode 100644 src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C create mode 100644 src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.H create mode 100644 src/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.C create mode 100644 src/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.H diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C index e53f8f68d3..15be3f9c1d 100644 --- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C +++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd. + \\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -33,12 +33,86 @@ Description #include "argList.H" #include "Time.H" #include "fvMesh.H" -#include "autoHexMeshDriver.H" +#include "autoRefineDriver.H" +#include "autoSnapDriver.H" +#include "autoLayerDriver.H" +#include "searchableSurfaces.H" +#include "refinementSurfaces.H" +#include "shellSurfaces.H" +#include "decompositionMethod.H" +#include "fvMeshDistribute.H" +#include "wallPolyPatch.H" +#include "refinementParameters.H" +#include "snapParameters.H" +#include "layerParameters.H" + using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Check writing tolerance before doing any serious work +scalar getMergeDistance(const polyMesh& mesh, const scalar mergeTol) +{ + const boundBox& meshBb = mesh.bounds(); + scalar mergeDist = mergeTol*mag(meshBb.max() - meshBb.min()); + scalar writeTol = std::pow + ( + scalar(10.0), + -scalar(IOstream::defaultPrecision()) + ); + + Info<< nl + << "Overall mesh bounding box : " << meshBb << nl + << "Relative tolerance : " << mergeTol << nl + << "Absolute matching distance : " << mergeDist << nl + << endl; + + if (mesh.time().writeFormat() == IOstream::ASCII && mergeTol < writeTol) + { + FatalErrorIn("getMergeDistance(const polyMesh&, const scalar)") + << "Your current settings specify ASCII writing with " + << IOstream::defaultPrecision() << " digits precision." << endl + << "Your merging tolerance (" << mergeTol << ") is finer than this." + << endl + << "Please change your writeFormat to binary" + << " or increase the writePrecision" << endl + << "or adjust the merge tolerance (-mergeTol)." + << exit(FatalError); + } + + return mergeDist; +} + + +// Write mesh and additional information +void writeMesh +( + const string& msg, + const meshRefinement& meshRefiner, + const label debug +) +{ + const fvMesh& mesh = meshRefiner.mesh(); + + meshRefiner.printMeshInfo(debug, msg); + Info<< "Writing mesh to time " << mesh.time().timeName() << endl; + + meshRefiner.write(meshRefinement::MESH|meshRefinement::SCALARLEVELS, ""); + if (debug & meshRefinement::OBJINTERSECTIONS) + { + meshRefiner.write + ( + meshRefinement::OBJINTERSECTIONS, + mesh.time().path()/mesh.time().timeName() + ); + } + Info<< "Written mesh in = " + << mesh.time().cpuTimeIncrement() << " s." << endl; +} + + + int main(int argc, char *argv[]) { # include "setRootCase.H" @@ -49,6 +123,11 @@ int main(int argc, char *argv[]) Info<< "Read mesh in = " << runTime.cpuTimeIncrement() << " s" << endl; + // Check patches and faceZones are synchronised + mesh.boundaryMesh().checkParallelSync(true); + meshRefinement::checkCoupledFaceZones(mesh); + + // Read decomposePar dictionary IOdictionary decomposeDict ( @@ -75,51 +154,282 @@ int main(int argc, char *argv[]) ) ); - // refinement parameters - const dictionary& refineDict = meshDict.subDict("castellatedMeshControls"); - // all surface geometry const dictionary& geometryDict = meshDict.subDict("geometry"); - // snap-to-surface parameters - const dictionary& snapDict = meshDict.subDict("snapControls"); + // refinement parameters + const dictionary& refineDict = meshDict.subDict("castellatedMeshControls"); // mesh motion and mesh quality parameters const dictionary& motionDict = meshDict.subDict("meshQualityControls"); + // snap-to-surface parameters + const dictionary& snapDict = meshDict.subDict("snapControls"); + // layer addition parameters const dictionary& layerDict = meshDict.subDict("addLayersControls"); - // Main meshing driver. Read surfaces. Determine initial intersections. - autoHexMeshDriver meshEngine + + // Debug + // ~~~~~ + + const label debug(readLabel(meshDict.lookup("debug"))); + if (debug > 0) + { + meshRefinement::debug = debug; + autoRefineDriver::debug = debug; + autoSnapDriver::debug = debug; + autoLayerDriver::debug = debug; + } + + + // Read geometry + // ~~~~~~~~~~~~~ + + searchableSurfaces allGeometry + ( + IOobject + ( + "abc", // dummy name + mesh.time().constant(), // directory + "triSurface", // instance + mesh.time(), // registry + IOobject::MUST_READ, + IOobject::NO_WRITE + ), + geometryDict + ); + + + // Read refinement surfaces + // ~~~~~~~~~~~~~~~~~~~~~~~~ + + Info<< "Reading refinement surfaces." << endl; + refinementSurfaces surfaces + ( + allGeometry, + refineDict.subDict("refinementSurfaces") + ); + Info<< "Read refinement surfaces in = " + << mesh.time().cpuTimeIncrement() << " s" << nl << endl; + + + // Read refinement shells + // ~~~~~~~~~~~~~~~~~~~~~~ + + Info<< "Reading refinement shells." << endl; + shellSurfaces shells + ( + allGeometry, + refineDict.subDict("refinementRegions") + ); + Info<< "Read refinement shells in = " + << mesh.time().cpuTimeIncrement() << " s" << nl << endl; + + + Info<< "Setting refinement level of surface to be consistent" + << " with shells." << endl; + surfaces.setMinLevelFields(shells); + Info<< "Checked shell refinement in = " + << mesh.time().cpuTimeIncrement() << " s" << nl << endl; + + + + + // Add all the surface regions as patches + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + labelList globalToPatch; + { + Info<< nl + << "Adding patches for surface regions" << nl + << "----------------------------------" << nl + << endl; + + // From global region number to mesh patch. + globalToPatch.setSize(surfaces.nRegions(), -1); + + Info<< "Patch\tRegion" << nl + << "-----\t------" + << endl; + + const labelList& surfaceGeometry = surfaces.surfaces(); + forAll(surfaceGeometry, surfI) + { + label geomI = surfaceGeometry[surfI]; + + const wordList& regNames = allGeometry.regionNames()[geomI]; + + Info<< surfaces.names()[surfI] << ':' << nl << nl; + + forAll(regNames, i) + { + label patchI = meshRefinement::addPatch + ( + mesh, + regNames[i], + wallPolyPatch::typeName + ); + + Info<< patchI << '\t' << regNames[i] << nl; + + globalToPatch[surfaces.globalRegion(surfI, i)] = patchI; + } + + Info<< nl; + } + Info<< "Added patches in = " + << mesh.time().cpuTimeIncrement() << " s" << nl << endl; + } + + + // Parallel + // ~~~~~~~~ + + // Decomposition + autoPtr decomposerPtr + ( + decompositionMethod::New + ( + decomposeDict, + mesh + ) + ); + decompositionMethod& decomposer = decomposerPtr(); + + if (Pstream::parRun() && !decomposer.parallelAware()) + { + FatalErrorIn(args.executable()) + << "You have selected decomposition method " + << decomposer.typeName + << " which is not parallel aware." << endl + << "Please select one that is (hierarchical, parMetis)" + << exit(FatalError); + } + + const scalar mergeDist = getMergeDistance ( mesh, - meshDict, // global control parameters - geometryDict, - refineDict, // refinement parameters - decomposeDict + readScalar(meshDict.lookup("mergeTolerance")) ); + + // Mesh distribution engine (uses tolerance to reconstruct meshes) + fvMeshDistribute distributor(mesh, mergeDist); + + + // Refinement engine + // ~~~~~~~~~~~~~~~~~ + + Info<< nl + << "Determining initial surface intersections" << nl + << "-----------------------------------------" << nl + << endl; + + // Main refinement engine + meshRefinement meshRefiner + ( + mesh, + mergeDist, // tolerance used in sorting coordinates + surfaces, // for surface intersection refinement + shells // for volume (inside/outside) refinement + ); + Info<< "Calculated surface intersections in = " + << mesh.time().cpuTimeIncrement() << " s" << nl << endl; + + // Some stats + meshRefiner.printMeshInfo(debug, "Initial mesh"); + + meshRefiner.write + ( + debug&meshRefinement::OBJINTERSECTIONS, + mesh.time().path()/mesh.time().timeName() + ); + + + + + // Now do the real work -refinement -snapping -layers + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Switch wantRefine(meshDict.lookup("castellatedMesh")); Switch wantSnap(meshDict.lookup("snap")); Switch wantLayers(meshDict.lookup("addLayers")); if (wantRefine) { - meshEngine.doRefine(refineDict, wantSnap); + autoRefineDriver refineDriver + ( + meshRefiner, + decomposer, + distributor, + globalToPatch + ); + + // Refinement parameters + refinementParameters refineParams(refineDict); + + refineDriver.doRefine(refineDict, refineParams, wantSnap); + + writeMesh + ( + "Refined mesh", + meshRefiner, + debug + ); } if (wantSnap) { - meshEngine.doSnap(snapDict, motionDict); + autoSnapDriver snapDriver + ( + meshRefiner, + globalToPatch + ); + + // Snap parameters + snapParameters snapParams(snapDict); + + snapDriver.doSnap(snapDict, motionDict, snapParams); + + writeMesh + ( + "Snapped mesh", + meshRefiner, + debug + ); } if (wantLayers) { - meshEngine.doLayers(layerDict, motionDict); + autoLayerDriver layerDriver + ( + meshRefiner, + globalToPatch + ); + + // Layer addition parameters + layerParameters layerParams(layerDict, mesh.boundaryMesh()); + + layerDriver.doLayers + ( + layerDict, + motionDict, + layerParams, + decomposer, + distributor + ); + + writeMesh + ( + "Layer mesh", + meshRefiner, + debug + ); } + Info<< "Finished meshing in = " << runTime.elapsedCpuTime() << " s." << endl; diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict index 4e71557fdb..e97b1ee9a7 100644 --- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict +++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict @@ -36,26 +36,26 @@ addLayers false; // - to 'snap' the mesh boundary to the surface geometry { -// box1x1x1 -// { -// type searchableBox; -// min (1.5 1 -0.5); -// max (3.5 2 0.5); -// } -// -// sphere.stl -// { -// type triSurfaceMesh; -// -// // Per region the patchname. If not provided will be _. -// regions -// { -// secondSolid -// { -// name mySecondPatch; -// } -// } -// } + box1x1x1 + { + type searchableBox; + min (1.5 1 -0.5); + max (3.5 2 0.5); + } + + sphere.stl + { + type triSurfaceMesh; + + // Per region the patchname. If not provided will be _. + regions + { + secondSolid + { + name mySecondPatch; + } + } + } sphere2 { @@ -159,11 +159,11 @@ castellatedMeshControls refinementRegions { - //box1x1x1 - //{ - // mode inside; - // levels ((1.0 4)); - //} + box1x1x1 + { + mode inside; + levels ((1.0 4)); + } //sphere.stl //{ // mode distance; diff --git a/src/autoMesh/Make/files b/src/autoMesh/Make/files index 1c763a316c..96141445be 100644 --- a/src/autoMesh/Make/files +++ b/src/autoMesh/Make/files @@ -1,10 +1,12 @@ autoHexMesh = autoHexMesh autoHexMeshDriver = $(autoHexMesh)/autoHexMeshDriver +$(autoHexMeshDriver)/autoLayerDriver.C +$(autoHexMeshDriver)/autoLayerDriverShrink.C +$(autoHexMeshDriver)/autoSnapDriver.C +$(autoHexMeshDriver)/autoRefineDriver.C $(autoHexMeshDriver)/autoHexMeshDriver.C -$(autoHexMeshDriver)/autoHexMeshDriverLayers.C -$(autoHexMeshDriver)/autoHexMeshDriverShrink.C -$(autoHexMeshDriver)/autoHexMeshDriverSnap.C + $(autoHexMeshDriver)/layerParameters/layerParameters.C $(autoHexMeshDriver)/refinementParameters/refinementParameters.C $(autoHexMeshDriver)/snapParameters/snapParameters.C diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C index 94c217ebcc..48f52d7880 100644 --- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C +++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C @@ -38,6 +38,10 @@ License #include "refinementParameters.H" #include "snapParameters.H" #include "layerParameters.H" +#include "autoRefineDriver.H" +#include "autoSnapDriver.H" +#include "autoLayerDriver.H" +#include "triSurfaceMesh.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -87,7 +91,10 @@ Foam::scalar Foam::autoHexMeshDriver::getMergeDistance(const scalar mergeTol) //// Specifically orient using a calculated point outside -//void Foam::autoHexMeshDriver::orientOutside(PtrList& shells) +//void Foam::autoHexMeshDriver::orientOutside +//( +// PtrList& shells +//) //{ // // Determine outside point. // boundBox overallBb @@ -124,7 +131,8 @@ Foam::scalar Foam::autoHexMeshDriver::getMergeDistance(const scalar mergeTol) // { // if (isA(shells[shellI])) // { -// triSurfaceMesh& shell = refCast(shells[shellI]); +// triSurfaceMesh& shell = +// refCast(shells[shellI]); // // if (!refinementSurfaces::isSurfaceClosed(shell)) // { @@ -141,584 +149,154 @@ Foam::scalar Foam::autoHexMeshDriver::getMergeDistance(const scalar mergeTol) //} -// Check that face zones are synced -void Foam::autoHexMeshDriver::checkCoupledFaceZones() const -{ - const faceZoneMesh& fZones = mesh_.faceZones(); - - // Check any zones are present anywhere and in same order - - { - List zoneNames(Pstream::nProcs()); - zoneNames[Pstream::myProcNo()] = fZones.names(); - Pstream::gatherList(zoneNames); - Pstream::scatterList(zoneNames); - // All have same data now. Check. - forAll(zoneNames, procI) - { - if (procI != Pstream::myProcNo()) - { - if (zoneNames[procI] != zoneNames[Pstream::myProcNo()]) - { - FatalErrorIn - ( - "autoHexMeshDriver::checkCoupledFaceZones() const" - ) << "faceZones are not synchronised on processors." << nl - << "Processor " << procI << " has faceZones " - << zoneNames[procI] << nl - << "Processor " << Pstream::myProcNo() - << " has faceZones " - << zoneNames[Pstream::myProcNo()] << nl - << exit(FatalError); - } - } - } - } - - // Check that coupled faces are present on both sides. - - labelList faceToZone(mesh_.nFaces()-mesh_.nInternalFaces(), -1); - - forAll(fZones, zoneI) - { - const faceZone& fZone = fZones[zoneI]; - - forAll(fZone, i) - { - label bFaceI = fZone[i]-mesh_.nInternalFaces(); - - if (bFaceI >= 0) - { - if (faceToZone[bFaceI] == -1) - { - faceToZone[bFaceI] = zoneI; - } - else if (faceToZone[bFaceI] == zoneI) - { - FatalErrorIn - ( - "autoHexMeshDriver::checkCoupledFaceZones()" - ) << "Face " << fZone[i] << " in zone " - << fZone.name() - << " is twice in zone!" - << abort(FatalError); - } - else - { - FatalErrorIn - ( - "autoHexMeshDriver::checkCoupledFaceZones()" - ) << "Face " << fZone[i] << " in zone " - << fZone.name() - << " is also in zone " - << fZones[faceToZone[bFaceI]].name() - << abort(FatalError); - } - } - } - } - - labelList neiFaceToZone(faceToZone); - syncTools::swapBoundaryFaceList(mesh_, neiFaceToZone, false); - - forAll(faceToZone, i) - { - if (faceToZone[i] != neiFaceToZone[i]) - { - FatalErrorIn - ( - "autoHexMeshDriver::checkCoupledFaceZones()" - ) << "Face " << mesh_.nInternalFaces()+i - << " is in zone " << faceToZone[i] - << ", its coupled face is in zone " << neiFaceToZone[i] - << abort(FatalError); - } - } -} - - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -//// Construct from components -//Foam::autoHexMeshDriver::autoHexMeshDriver -//( -// fvMesh& mesh, -// const dictionary& dict, -// const dictionary& decomposeDict -//) -//: -// mesh_(mesh), -// dict_(dict), -// debug_(readLabel(dict_.lookup("debug"))), -// mergeDist_(getMergeDistance(readScalar(dict_.lookup("mergeTolerance")))) -//{ -// if (debug_ > 0) -// { -// meshRefinement::debug = debug_; -// autoHexMeshDriver::debug = debug_; -// } -// -// refinementParameters refineParams(dict); -// -// Info<< "Overall cell limit : " -// << refineParams.maxGlobalCells() << endl; -// Info<< "Per processor cell limit : " -// << refineParams.maxLocalCells() << endl; -// Info<< "Minimum number of cells to refine : " -// << refineParams.minRefineCells() << endl; -// Info<< "Curvature : " -// << refineParams.curvature() << nl << endl; -// Info<< "Layers between different refinement levels : " -// << refineParams.nBufferLayers() << endl; -// -////XXXXX -// PtrList shellsDict(dict_.lookup("refinementShells")); -// -// PtrList surfacesDict(dict_.lookup("surfaces")); -// -// -// // Read geometry -// // ~~~~~~~~~~~~~ -// -// { -// Info<< "Reading all geometry." << endl; -// -// // Construct dictionary with all shells and all refinement surfaces -// dictionary geometryDict; -// -// forAll(shellsDict, shellI) -// { -// dictionary shellDict = shellsDict[shellI]; -// const word name(shellDict.lookup("name")); -// shellDict.remove("name"); -// shellDict.remove("level"); -// shellDict.remove("refineInside"); -// geometryDict.add(name, shellDict); -// } -// -// forAll(surfacesDict, surfI) -// { -// dictionary surfDict = surfacesDict[shellI]; -// const word name(string::validate(surfDict.lookup("file"))); -// surfDict.remove("file"); -// if (!surfDict.found("name")) -// { -// surfDict.add("name", name); -// } -// geometryDict.add(name, iter()); -// } -// -// allGeometryPtr_.reset -// ( -// new searchableSurfaces -// ( -// IOobject -// ( -// "abc", // dummy name -// mesh_.time().constant(), // directory -// "triSurface", // instance -// mesh_.time(), // registry -// IOobject::MUST_READ, -// IOobject::NO_WRITE -// ), -// geometryDict -// ) -// ); -// -// Info<< "Read geometry in = " -// << mesh_.time().cpuTimeIncrement() << " s" << nl << endl; -// } -// -// -// // Read refinement surfaces -// // ~~~~~~~~~~~~~~~~~~~~~~~~ -// -// { -// Info<< "Reading surfaces and constructing search trees." << endl; -// -// surfacesPtr_.reset -// ( -// new refinementSurfaces -// ( -// allGeometryPtr_(), -// surfacesDict -// ) -// ); -// Info<< "Read surfaces in = " -// << mesh_.time().cpuTimeIncrement() << " s" << endl; -// } -// -// // Read refinement shells -// // ~~~~~~~~~~~~~~~~~~~~~~ -// -// { -// Info<< "Reading refinement shells." << endl; -// -// PtrList shellDicts(dict_.lookup("refinementShells")); -// -// shells_.setSize(shellDicts.size()); -// shellLevels_.setSize(shellDicts.size()); -// shellRefineInside_.setSize(shellDicts.size()); -// -// forAll(shellDicts, i) -// { -// const dictionary& dict = shellDicts[i]; -// -// shells_.set -// ( -// i, -// searchableSurface::New -// ( -// dict.lookup("type"), -// dict.lookup("name"), -// mesh_.time(), -// dict -// ) -// ); -// shellLevels_[i] = readLabel(dict.lookup("level")); -// shellRefineInside_[i] = Switch(dict.lookup("refineInside")); -// -// if (shellRefineInside_[i]) -// { -// Info<< "Refinement level " << shellLevels_[i] -// << " for all cells inside " << shells_[i].name() << endl; -// } -// else -// { -// Info<< "Refinement level " << shellLevels_[i] -// << " for all cells outside " << shells_[i].name() << endl; -// } -// } -// -// Info<< "Read refinement shells in = " -// << mesh_.time().cpuTimeIncrement() << " s" << endl; -// -// // Orient shell surfaces before any searching is done. -// Info<< "Orienting triSurface shells so point far away is outside." -// << endl; -// orientOutside(shells_); -// Info<< "Oriented shells in = " -// << mesh_.time().cpuTimeIncrement() << " s" << endl; -// } -// -// -// // Read refinement surfaces -// // ~~~~~~~~~~~~~~~~~~~~~~~~ -// -// { -// Info<< "Reading surfaces and constructing search trees." << endl; -// -// surfacesPtr_.reset -// ( -// new refinementSurfaces -// ( -// IOobject -// ( -// "", // dummy name -// mesh_.time().constant(), // directory -// "triSurface", // instance -// mesh_.time(), // registry -// IOobject::MUST_READ, -// IOobject::NO_WRITE -// ), -// dict_.lookup("surfaces") -// ) -// ); -// Info<< "Read surfaces in = " -// << mesh_.time().cpuTimeIncrement() << " s" << endl; -// -// // Orient surfaces (if they're closed) before any searching is done. -// Info<< "Orienting (closed) surfaces so keepPoint is outside." << endl; -// forAll(surfaces(), i) -// { -// if (refinementSurfaces::isSurfaceClosed(surfaces()[i])) -// { -// refinementSurfaces::orientSurface -// ( -// keepPoints_[0], -// surfacesPtr_()[i] -// ); -// } -// } -// Info<< "Oriented closed surfaces in = " -// << mesh_.time().cpuTimeIncrement() << " s" << endl; -// -// Info<< "Setting refinement level of surface to be consistent" -// << " with shells." << endl; -// surfacesPtr_().setMinLevelFields -// ( -// shells_, -// shellLevels_, -// shellRefineInside_ -// ); -// Info<< "Checked shell refinement in = " -// << mesh_.time().cpuTimeIncrement() << " s" << endl; -// } -// -// // Check faceZones are synchronised -// checkCoupledFaceZones(); -// -// -// // Add all the surface regions as patches -// // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// { -// Info<< nl -// << "Adding patches for surface regions" << nl -// << "----------------------------------" << nl -// << endl; -// -// // From global region number to mesh patch. -// globalToPatch_.setSize(surfaces().nRegions(), -1); -// -// Info<< "Patch\tRegion" << nl -// << "-----\t------" -// << endl; -// -// forAll(surfaces(), surfI) -// { -// const triSurfaceMesh& s = surfaces()[surfI]; -// -// Info<< surfaces().names()[surfI] << ':' << nl << nl; -// -// const geometricSurfacePatchList& regions = s.patches(); -// -// labelList nTrisPerRegion(surfaces().countRegions(s)); -// -// forAll(regions, i) -// { -// if (nTrisPerRegion[i] > 0) -// { -// label globalRegionI = surfaces().globalRegion(surfI, i); -// -// // Use optionally specified patch type and name -// word patchType = surfaces().patchType()[globalRegionI]; -// if (patchType == "") -// { -// patchType = wallPolyPatch::typeName; -// } -// -// word patchName = surfaces().patchName()[globalRegionI]; -// if (patchName == "") -// { -// patchName = -// surfaces().names()[surfI] -// + '_' -// + regions[i].name(); -// } -// -// label patchI = meshRefinement::addPatch -// ( -// mesh, -// patchName, -// patchType -// ); -// -// Info<< patchI << '\t' << regions[i].name() << nl; -// -// globalToPatch_[globalRegionI] = patchI; -// } -// } -// -// Info<< nl; -// } -// Info<< "Added patches in = " -// << mesh_.time().cpuTimeIncrement() << " s" << endl; -// } -// -// -// //// Add cyclics for any named faceZones -// //// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// //// (these cyclics are used later on to temporarily put the faceZones -// //// in when snapping) -// // -// //labelList namedSurfaces(surfaces().getNamedSurfaces()); -// //if (namedSurfaces.size() > 0) -// //{ -// // Info<< nl -// // << "Introducing cyclics for faceZones" << nl -// // << "---------------------------------" << nl -// // << endl; -// // -// // // From surface to cyclic patch -// // surfaceToCyclicPatch_.setSize(surfaces().size(), -1); -// // -// // Info<< "Patch\tZone" << nl -// // << "----\t-----" -// // << endl; -// // -// // forAll(namedSurfaces, i) -// // { -// // label surfI = namedSurfaces[i]; -// // -// // surfaceToCyclicPatch_[surfI] = meshRefinement::addPatch -// // ( -// // mesh, -// // surfaces().faceZoneNames()[surfI], -// // cyclicPolyPatch::typeName -// // ); -// // -// // Info<< surfaceToCyclicPatch_[surfI] << '\t' -// // << surfaces().faceZoneNames()[surfI] << nl << endl; -// // } -// // Info<< "Added cyclic patches in = " -// // << mesh_.time().cpuTimeIncrement() << " s" << endl; -// //} -// -// -// // Parallel -// // ~~~~~~~~ -// -// { -// // Decomposition -// decomposerPtr_ = decompositionMethod::New -// ( -// decomposeDict, -// mesh_ -// ); -// decompositionMethod& decomposer = decomposerPtr_(); -// -// -// if (Pstream::parRun() && !decomposer.parallelAware()) -// { -// FatalErrorIn("autoHexMeshDriver::autoHexMeshDriver" -// "(const IOobject&, fvMesh&)") -// << "You have selected decomposition method " -// << decomposer.typeName -// << " which is not parallel aware." << endl -// << "Please select one that is (parMetis, hierarchical)" -// << exit(FatalError); -// } -// -// // Mesh distribution engine (uses tolerance to reconstruct meshes) -// distributorPtr_.reset(new fvMeshDistribute(mesh_, mergeDist_)); -// } -// -// -// // Refinement engine -// // ~~~~~~~~~~~~~~~~~ -// -// { -// Info<< nl -// << "Determining initial surface intersections" << nl -// << "-----------------------------------------" << nl -// << endl; -// -// // Main refinement engine -// meshRefinerPtr_.reset -// ( -// new meshRefinement -// ( -// mesh, -// mergeDist_, // tolerance used in sorting coordinates -// surfaces() -// ) -// ); -// Info<< "Calculated surface intersections in = " -// << mesh_.time().cpuTimeIncrement() << " s" << endl; -// -// // Some stats -// meshRefinerPtr_().printMeshInfo(debug_, "Initial mesh"); -// -// meshRefinerPtr_().write -// ( -// debug_&meshRefinement::OBJINTERSECTIONS, -// mesh_.time().path()/mesh_.time().timeName() -// ); -// } -//} - - -// Construct from separate dictionaries. +// Construct from components Foam::autoHexMeshDriver::autoHexMeshDriver ( fvMesh& mesh, - const dictionary& controlDict, - const dictionary& geometryDict, - const dictionary& refineDict, + const dictionary& dict, const dictionary& decomposeDict ) : mesh_(mesh), - dict_(controlDict), - debug_(readLabel(controlDict.lookup("debug"))), - mergeDist_ - ( - getMergeDistance(readScalar(controlDict.lookup("mergeTolerance"))) - ) + dict_(dict), + debug_(readLabel(dict_.lookup("debug"))), + mergeDist_(getMergeDistance(readScalar(dict_.lookup("mergeTolerance")))) { if (debug_ > 0) { meshRefinement::debug = debug_; autoHexMeshDriver::debug = debug_; + autoRefineDriver::debug = debug; + autoSnapDriver::debug = debug; + autoLayerDriver::debug = debug; } + refinementParameters refineParams(dict, 1); + + Info<< "Overall cell limit : " + << refineParams.maxGlobalCells() << endl; + Info<< "Per processor cell limit : " + << refineParams.maxLocalCells() << endl; + Info<< "Minimum number of cells to refine : " + << refineParams.minRefineCells() << endl; + Info<< "Curvature : " + << refineParams.curvature() << nl << endl; + Info<< "Layers between different refinement levels : " + << refineParams.nBufferLayers() << endl; + + PtrList shellDicts(dict_.lookup("refinementShells")); + + PtrList surfaceDicts(dict_.lookup("surfaces")); + + // Read geometry // ~~~~~~~~~~~~~ - Info<< "Reading all geometry." << endl; - allGeometryPtr_.reset - ( - new searchableSurfaces + { + Info<< "Reading all geometry." << endl; + + // Construct dictionary with all shells and all refinement surfaces + dictionary geometryDict; + + forAll(shellDicts, shellI) + { + dictionary shellDict = shellDicts[shellI]; + const word name(shellDict.lookup("name")); + shellDict.remove("name"); + shellDict.remove("level"); + shellDict.remove("refineInside"); + geometryDict.add(name, shellDict); + } + + forAll(surfaceDicts, surfI) + { + dictionary surfDict = surfaceDicts[surfI]; + const word name(string::validate(surfDict.lookup("file"))); + surfDict.remove("file"); + surfDict.remove("regions"); + if (!surfDict.found("name")) + { + surfDict.add("name", name); + } + surfDict.add("type", triSurfaceMesh::typeName); + geometryDict.add(name, surfDict); + } + + allGeometryPtr_.reset ( - IOobject + new searchableSurfaces ( - "abc", // dummy name - mesh_.time().constant(), // directory - "triSurface", // instance - mesh_.time(), // registry - IOobject::MUST_READ, - IOobject::NO_WRITE - ), - geometryDict - ) - ); - Info<< "Read geometry in = " - << mesh_.time().cpuTimeIncrement() << " s" << nl << endl; + IOobject + ( + "abc", // dummy name + mesh_.time().constant(), // directory + "triSurface", // instance + mesh_.time(), // registry + IOobject::MUST_READ, + IOobject::NO_WRITE + ), + geometryDict + ) + ); + + Info<< "Read geometry in = " + << mesh_.time().cpuTimeIncrement() << " s" << endl; + } // Read refinement surfaces // ~~~~~~~~~~~~~~~~~~~~~~~~ - Info<< "Reading refinement surfaces." << endl; - surfacesPtr_.reset - ( - new refinementSurfaces - ( - allGeometryPtr_(), - refineDict.subDict("refinementSurfaces") - ) - ); - Info<< "Read refinement surfaces in = " - << mesh_.time().cpuTimeIncrement() << " s" << nl << endl; + { + Info<< "Reading surfaces and constructing search trees." << endl; + surfacesPtr_.reset + ( + new refinementSurfaces + ( + allGeometryPtr_(), + surfaceDicts + ) + ); + Info<< "Read surfaces in = " + << mesh_.time().cpuTimeIncrement() << " s" << endl; + } // Read refinement shells // ~~~~~~~~~~~~~~~~~~~~~~ - Info<< "Reading refinement shells." << endl; - shellsPtr_.reset - ( - new shellSurfaces + { + Info<< "Reading refinement shells." << endl; + shellsPtr_.reset ( - allGeometryPtr_(), - refineDict.subDict("refinementRegions") - ) - ); - Info<< "Read refinement shells in = " - << mesh_.time().cpuTimeIncrement() << " s" << nl << endl; + new shellSurfaces + ( + allGeometryPtr_(), + shellDicts + ) + ); + Info<< "Read refinement shells in = " + << mesh_.time().cpuTimeIncrement() << " s" << endl; + //// Orient shell surfaces before any searching is done. + //Info<< "Orienting triSurface shells so point far away is outside." + // << endl; + //orientOutside(shells_); + //Info<< "Oriented shells in = " + // << mesh_.time().cpuTimeIncrement() << " s" << endl; - Info<< "Setting refinement level of surface to be consistent" - << " with shells." << endl; - surfacesPtr_().setMinLevelFields(shells()); - Info<< "Checked shell refinement in = " - << mesh_.time().cpuTimeIncrement() << " s" << nl << endl; - + Info<< "Setting refinement level of surface to be consistent" + << " with shells." << endl; + surfacesPtr_().setMinLevelFields(shells()); + Info<< "Checked shell refinement in = " + << mesh_.time().cpuTimeIncrement() << " s" << endl; + } // Check faceZones are synchronised - checkCoupledFaceZones(); + meshRefinement::checkCoupledFaceZones(mesh_); // Add all the surface regions as patches @@ -757,7 +335,6 @@ Foam::autoHexMeshDriver::autoHexMeshDriver label patchI = meshRefinement::addPatch ( mesh, - //s.searchableSurface::name() + '_' + regions[i].name(), regNames[i], wallPolyPatch::typeName ); @@ -774,6 +351,46 @@ Foam::autoHexMeshDriver::autoHexMeshDriver << mesh_.time().cpuTimeIncrement() << " s" << nl << endl; } + + //// Add cyclics for any named faceZones + //// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + //// (these cyclics are used later on to temporarily put the faceZones + //// in when snapping) + // + //labelList namedSurfaces(surfaces().getNamedSurfaces()); + //if (namedSurfaces.size() > 0) + //{ + // Info<< nl + // << "Introducing cyclics for faceZones" << nl + // << "---------------------------------" << nl + // << endl; + // + // // From surface to cyclic patch + // surfaceToCyclicPatch_.setSize(surfaces().size(), -1); + // + // Info<< "Patch\tZone" << nl + // << "----\t-----" + // << endl; + // + // forAll(namedSurfaces, i) + // { + // label surfI = namedSurfaces[i]; + // + // surfaceToCyclicPatch_[surfI] = meshRefinement::addPatch + // ( + // mesh, + // surfaces().faceZoneNames()[surfI], + // cyclicPolyPatch::typeName + // ); + // + // Info<< surfaceToCyclicPatch_[surfI] << '\t' + // << surfaces().faceZoneNames()[surfI] << nl << endl; + // } + // Info<< "Added cyclic patches in = " + // << mesh_.time().cpuTimeIncrement() << " s" << endl; + //} + + // Parallel // ~~~~~~~~ @@ -789,7 +406,8 @@ Foam::autoHexMeshDriver::autoHexMeshDriver if (Pstream::parRun() && !decomposer.parallelAware()) { - FatalErrorIn("autoHexMeshDriver::autoHexMeshDriver(const IOobject&, fvMesh&)") + FatalErrorIn("autoHexMeshDriver::autoHexMeshDriver" + "(const IOobject&, fvMesh&)") << "You have selected decomposition method " << decomposer.typeName << " which is not parallel aware." << endl @@ -818,12 +436,12 @@ Foam::autoHexMeshDriver::autoHexMeshDriver ( mesh, mergeDist_, // tolerance used in sorting coordinates - surfaces(), // for surface intersection refinement - shells() // for volume (inside/outside) refinement + surfaces(), + shells() ) ); Info<< "Calculated surface intersections in = " - << mesh_.time().cpuTimeIncrement() << " s" << nl << endl; + << mesh_.time().cpuTimeIncrement() << " s" << endl; // Some stats meshRefinerPtr_().printMeshInfo(debug_, "Initial mesh"); @@ -839,751 +457,6 @@ Foam::autoHexMeshDriver::autoHexMeshDriver // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -// Read explicit feature edges -Foam::label Foam::autoHexMeshDriver::readFeatureEdges -( - const PtrList& featDicts -) -{ - Info<< "Reading external feature lines." << endl; - - featureMeshes_.setSize(featDicts.size()); - featureLevels_.setSize(featDicts.size()); - - forAll(featDicts, i) - { - const dictionary& dict = featDicts[i]; - - fileName featFileName(dict.lookup("file")); - - featureMeshes_.set - ( - i, - new featureEdgeMesh - ( - IOobject - ( - featFileName, // name - mesh_.time().constant(),// directory - "triSurface", // instance - mesh_.db(), // registry - IOobject::MUST_READ, - IOobject::NO_WRITE, - false - ) - ) - ); - - featureMeshes_[i].mergePoints(mergeDist_); - featureLevels_[i] = readLabel(dict.lookup("level")); - - Info<< "Refinement level " << featureLevels_[i] - << " for all cells crossed by feature " << featFileName - << " (" << featureMeshes_[i].points().size() << " points, " - << featureMeshes_[i].edges().size() << ")." << endl; - } - - Info<< "Read feature lines in = " - << mesh_.time().cpuTimeIncrement() << " s" << nl << endl; - - return featureMeshes_.size(); -} - - -Foam::label Foam::autoHexMeshDriver::featureEdgeRefine -( - const refinementParameters& refineParams, - const PtrList& featDicts, - const label maxIter, - const label minRefine -) -{ - // Read explicit feature edges - readFeatureEdges(featDicts); - - meshRefinement& meshRefiner = meshRefinerPtr_(); - - label iter = 0; - - if (featureMeshes_.size() > 0 && maxIter > 0) - { - for (; iter < maxIter; iter++) - { - Info<< nl - << "Feature refinement iteration " << iter << nl - << "------------------------------" << nl - << endl; - - labelList candidateCells - ( - meshRefiner.refineCandidates - ( - refineParams.keepPoints()[0], // For now only use one. - refineParams.curvature(), - - featureMeshes_, - featureLevels_, - - true, // featureRefinement - false, // internalRefinement - false, // surfaceRefinement - false, // curvatureRefinement - refineParams.maxGlobalCells(), - refineParams.maxLocalCells() - ) - ); - labelList cellsToRefine - ( - meshRefiner.meshCutter().consistentRefinement - ( - candidateCells, - true - ) - ); - Info<< "Determined cells to refine in = " - << mesh_.time().cpuTimeIncrement() << " s" << endl; - - - - label nCellsToRefine = cellsToRefine.size(); - reduce(nCellsToRefine, sumOp