diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C index 7fcf53e935..fef49a3fe6 100644 --- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C +++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C @@ -434,6 +434,19 @@ int main(int argc, char *argv[]) // Layer addition parameters layerParameters layerParams(layerDict, mesh.boundaryMesh()); + //!!! Temporary hack to get access to maxLocalCells + bool preBalance; + { + refinementParameters refineParams(refineDict); + + preBalance = returnReduce + ( + (mesh.nCells() >= refineParams.maxLocalCells()), + orOp() + ); + } + + if (!overwrite) { const_cast(mesh.time())++; @@ -444,6 +457,7 @@ int main(int argc, char *argv[]) layerDict, motionDict, layerParams, + preBalance, decomposer, distributor ); diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict index 783469ee7d..dab2d1d064 100644 --- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict +++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict @@ -10,7 +10,7 @@ FoamFile version 2.0; format ascii; class dictionary; - object autoHexMeshDict; + object snappyHexMeshDict; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -40,7 +40,7 @@ geometry { type triSurfaceMesh; - //tolerance 1E-6; // optional:non-default tolerance on intersections + //tolerance 1E-5; // optional:non-default tolerance on intersections //maxTreeDepth 10; // optional:depth of octree. Decrease only in case // of memory limitations. @@ -71,9 +71,9 @@ castellatedMeshControls // Refinement parameters // ~~~~~~~~~~~~~~~~~~~~~ - // While refining maximum number of cells per processor. This is basically - // the number of cells that fit on a processor. If you choose this too small - // it will do just more refinement iterations to obtain a similar mesh. + // If local number of cells is >= maxLocalCells on any processor + // switches from from refinement followed by balancing + // (current method) to (weighted) balancing before refinement. maxLocalCells 1000000; // Overall cell limit (approximately). Refinement will stop immediately @@ -89,6 +89,13 @@ castellatedMeshControls // (unless the number of cells to refine is 0) minRefinementCells 0; + // Allow a certain level of imbalance during refining + // (since balancing is quite expensive) + // Expressed as fraction of perfect balance (= overall number of cells / + // nProcs). 0=balance always. + maxLoadUnbalance 0.10; + + // Number of buffer layers between different levels. // 1 means normal 2:1 refinement restriction, larger means slower // refinement. diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C index cc110c1d40..76e589c039 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C @@ -539,6 +539,7 @@ void Foam::autoHexMeshDriver::doMesh() shrinkDict, motionDict, layerParams, + true, // pre-balance decomposerPtr_(), distributorPtr_() ); diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C index 5fcf18a025..d416d11033 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C @@ -2497,18 +2497,13 @@ void Foam::autoLayerDriver::mergePatchFacesUndo << "---------------------------" << nl << " - which are on the same patch" << nl << " - which make an angle < " << layerParams.featureAngle() - << "- which are on the same patch" << nl - << "- which make an angle < " << layerParams.featureAngle() << " degrees" << nl << " (cos:" << minCos << ')' << nl << " - as long as the resulting face doesn't become concave" - << " (cos:" << minCos << ')' << nl - << "- as long as the resulting face doesn't become concave" << " by more than " << layerParams.concaveAngle() << " degrees" << nl << " (0=straight, 180=fully concave)" << nl - << " (0=straight, 180=fully concave)" << nl << endl; label nChanged = mergePatchFacesUndo(minCos, concaveCos, motionDict); @@ -3241,6 +3236,7 @@ void Foam::autoLayerDriver::doLayers const dictionary& shrinkDict, const dictionary& motionDict, const layerParameters& layerParams, + const bool preBalance, decompositionMethod& decomposer, fvMeshDistribute& distributor ) @@ -3299,6 +3295,7 @@ void Foam::autoLayerDriver::doLayers // Balance if (Pstream::parRun()) + if (Pstream::parRun() && preBalance) { Info<< nl << "Doing initial balancing" << nl diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H index fa02d3d0ee..748f26d85e 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H @@ -535,6 +535,7 @@ public: const dictionary& shrinkDict, const dictionary& motionDict, const layerParameters& layerParams, + const bool preBalance, // balance before adding? decompositionMethod& decomposer, fvMeshDistribute& distributor ); diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C index 6d38767737..586dd926ce 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C @@ -205,14 +205,36 @@ Foam::label Foam::autoRefineDriver::featureEdgeRefine const_cast(mesh.time())++; } - meshRefiner_.refineAndBalance + + if ( - "feature refinement iteration " + name(iter), - decomposer_, - distributor_, - cellsToRefine, - refineParams.maxLoadUnbalance() - ); + returnReduce + ( + (mesh.nCells() >= refineParams.maxLocalCells()), + orOp() + ) + ) + { + meshRefiner_.balanceAndRefine + ( + "feature refinement iteration " + name(iter), + decomposer_, + distributor_, + cellsToRefine, + refineParams.maxLoadUnbalance() + ); + } + else + { + meshRefiner_.refineAndBalance + ( + "feature refinement iteration " + name(iter), + decomposer_, + distributor_, + cellsToRefine, + refineParams.maxLoadUnbalance() + ); + } } } return iter; @@ -306,14 +328,36 @@ Foam::label Foam::autoRefineDriver::surfaceOnlyRefine const_cast(mesh.time())++; } - meshRefiner_.refineAndBalance + + if ( - "surface refinement iteration " + name(iter), - decomposer_, - distributor_, - cellsToRefine, - refineParams.maxLoadUnbalance() - ); + returnReduce + ( + (mesh.nCells() >= refineParams.maxLocalCells()), + orOp() + ) + ) + { + meshRefiner_.balanceAndRefine + ( + "surface refinement iteration " + name(iter), + decomposer_, + distributor_, + cellsToRefine, + refineParams.maxLoadUnbalance() + ); + } + else + { + meshRefiner_.refineAndBalance + ( + "surface refinement iteration " + name(iter), + decomposer_, + distributor_, + cellsToRefine, + refineParams.maxLoadUnbalance() + ); + } } return iter; } @@ -491,14 +535,35 @@ Foam::label Foam::autoRefineDriver::shellRefine const_cast(mesh.time())++; } - meshRefiner_.refineAndBalance + if ( - "shell refinement iteration " + name(iter), - decomposer_, - distributor_, - cellsToRefine, - refineParams.maxLoadUnbalance() - ); + returnReduce + ( + (mesh.nCells() >= refineParams.maxLocalCells()), + orOp() + ) + ) + { + meshRefiner_.balanceAndRefine + ( + "shell refinement iteration " + name(iter), + decomposer_, + distributor_, + cellsToRefine, + refineParams.maxLoadUnbalance() + ); + } + else + { + meshRefiner_.refineAndBalance + ( + "shell refinement iteration " + name(iter), + decomposer_, + distributor_, + cellsToRefine, + refineParams.maxLoadUnbalance() + ); + } } meshRefiner_.userFaceData().clear(); diff --git a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H index 6347570cac..7e857c0ba2 100644 --- a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H +++ b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H @@ -656,6 +656,16 @@ public: const scalar maxLoadUnbalance ); + //- Balance before refining some cells + autoPtr balanceAndRefine + ( + const string& msg, + decompositionMethod& decomposer, + fvMeshDistribute& distributor, + const labelList& cellsToRefine, + const scalar maxLoadUnbalance + ); + // Baffle handling diff --git a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C index cd35891b3f..fde478a91a 100644 --- a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C +++ b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C @@ -219,7 +219,6 @@ Foam::labelList Foam::meshRefinement::getChangedFaces << endl; faceSet changedFacesSet(mesh, "changedFaces", changedFaces); - changedFacesSet.instance() = mesh.time().timeName(); Pout<< "getChangedFaces : Writing " << changedFaces.size() << " changed faces to faceSet " << changedFacesSet.name() << endl; @@ -1246,90 +1245,110 @@ Foam::autoPtr Foam::meshRefinement::refine } -//// Do refinement of consistent set of cells followed by truncation and -//// load balancing. -//Foam::autoPtr -//Foam::meshRefinement::refineAndBalance -//( -// const string& msg, -// decompositionMethod& decomposer, -// fvMeshDistribute& distributor, -// const labelList& cellsToRefine -//) -//{ -// // Do all refinement -// refine(cellsToRefine); -// -// if (debug) -// { -// Pout<< "Writing refined but unbalanced " << msg -// << " mesh to time " << timeName() << endl; -// write -// ( -// debug, -// mesh_.time().path() -// /timeName() -// ); -// Pout<< "Dumped debug data in = " -// << mesh_.time().cpuTimeIncrement() << " s" << endl; -// -// // test all is still synced across proc patches -// checkData(); -// } -// -// Info<< "Refined mesh in = " -// << mesh_.time().cpuTimeIncrement() << " s" << endl; -// printMeshInfo(debug, "After refinement " + msg); -// -// -// // Load balancing -// // ~~~~~~~~~~~~~~ -// -// autoPtr distMap; -// -// if (Pstream::nProcs() > 1) -// { -// scalarField cellWeights(mesh_.nCells(), 1); -// -// distMap = balance -// ( -// false, //keepZoneFaces -// false, //keepBaffles -// cellWeights, -// decomposer, -// distributor -// ); -// -// Info<< "Balanced mesh in = " -// << mesh_.time().cpuTimeIncrement() << " s" << endl; -// -// printMeshInfo(debug, "After balancing " + msg); -// -// -// if (debug) -// { -// Pout<< "Writing balanced " << msg -// << " mesh to time " << timeName() << endl; -// write -// ( -// debug, -// mesh_.time().path()/timeName() -// ); -// Pout<< "Dumped debug data in = " -// << mesh_.time().cpuTimeIncrement() << " s" << endl; -// -// // test all is still synced across proc patches -// checkData(); -// } -// } -// -// return distMap; -//} +// Do refinement of consistent set of cells followed by truncation and +// load balancing. +Foam::autoPtr +Foam::meshRefinement::refineAndBalance +( + const string& msg, + decompositionMethod& decomposer, + fvMeshDistribute& distributor, + const labelList& cellsToRefine, + const scalar maxLoadUnbalance +) +{ + // Do all refinement + refine(cellsToRefine); + + if (debug) + { + Pout<< "Writing refined but unbalanced " << msg + << " mesh to time " << timeName() << endl; + write + ( + debug, + mesh_.time().path() + /timeName() + ); + Pout<< "Dumped debug data in = " + << mesh_.time().cpuTimeIncrement() << " s" << endl; + + // test all is still synced across proc patches + checkData(); + } + + Info<< "Refined mesh in = " + << mesh_.time().cpuTimeIncrement() << " s" << endl; + printMeshInfo(debug, "After refinement " + msg); + + + // Load balancing + // ~~~~~~~~~~~~~~ + + autoPtr distMap; + + if (Pstream::nProcs() > 1) + { + scalar nIdealCells = + mesh_.globalData().nTotalCells() + / Pstream::nProcs(); + + scalar unbalance = returnReduce + ( + mag(1.0-mesh_.nCells()/nIdealCells), + maxOp() + ); + + if (unbalance <= maxLoadUnbalance) + { + Info<< "Skipping balancing since max unbalance " << unbalance + << " is less than allowable " << maxLoadUnbalance + << endl; + } + else + { + scalarField cellWeights(mesh_.nCells(), 1); + + distMap = balance + ( + false, //keepZoneFaces + false, //keepBaffles + cellWeights, + decomposer, + distributor + ); + + Info<< "Balanced mesh in = " + << mesh_.time().cpuTimeIncrement() << " s" << endl; + + printMeshInfo(debug, "After balancing " + msg); + + + if (debug) + { + Pout<< "Writing balanced " << msg + << " mesh to time " << timeName() << endl; + write + ( + debug, + mesh_.time().path()/timeName() + ); + Pout<< "Dumped debug data in = " + << mesh_.time().cpuTimeIncrement() << " s" << endl; + + // test all is still synced across proc patches + checkData(); + } + } + } + + return distMap; +} // Do load balancing followed by refinement of consistent set of cells. Foam::autoPtr -Foam::meshRefinement::refineAndBalance +Foam::meshRefinement::balanceAndRefine ( const string& msg, decompositionMethod& decomposer, @@ -1386,8 +1405,8 @@ Foam::meshRefinement::refineAndBalance if (unbalance <= maxLoadUnbalance) { Info<< "Skipping balancing since max unbalance " << unbalance - << " in = " - << mesh_.time().cpuTimeIncrement() << " s" << endl; + << " is less than allowable " << maxLoadUnbalance + << endl; } else { diff --git a/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict b/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict index 94282655bb..14b7a8fa0b 100644 --- a/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict +++ b/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict @@ -116,9 +116,9 @@ castellatedMeshControls // Refinement parameters // ~~~~~~~~~~~~~~~~~~~~~ - // While refining maximum number of cells per processor. This is basically - // the number of cells that fit on a processor. If you choose this too small - // it will do just more refinement iterations to obtain a similar mesh. + // If local number of cells is >= maxLocalCells on any processor + // switches from from refinement followed by balancing + // (current method) to (weighted) balancing before refinement. maxLocalCells 1000000; // Overall cell limit (approximately). Refinement will stop immediately @@ -255,6 +255,8 @@ snapControls // Settings for the layer addition. addLayersControls { + // Are the thickness parameters below relative to the undistorted + // size of the refined cell outside layer (true) or absolute sizes (false). relativeSizes true; // Per final patch (so not geometry!) the layer information @@ -277,11 +279,14 @@ addLayersControls // is the // thickness of the layer furthest away from the wall. // Relative to undistorted size of cell outside layer. + // is the thickness of the layer furthest away from the wall. + // See relativeSizes parameter. finalLayerThickness 0.5; //- Minimum thickness of cell layer. If for any reason layer // cannot be above minThickness do not add layer. // Relative to undistorted size of cell outside layer. + // See relativeSizes parameter. minThickness 0.25; //- If points get not extruded do nGrow layers of connected faces that are @@ -323,7 +328,10 @@ addLayersControls // Create buffer region for new layer terminations nBufferCellsNoExtrude 0; - // Overall max number of layer addition iterations + + // Overall max number of layer addition iterations. The mesher will exit + // if it reaches this number of iterations; possibly with an illegal + // mesh. nLayerIter 50; } @@ -349,6 +357,7 @@ meshQualityControls minFlatness 0.5; //- Minimum pyramid volume. Is absolute volume of cell pyramid. + // Set to a sensible fraction of the smallest cell volume expected. // Set to very negative number (e.g. -1E30) to disable. minVol 1e-13; diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/system/snappyHexMeshDict b/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/system/snappyHexMeshDict index 3c6c4509ed..bb6fb94f13 100644 --- a/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/system/snappyHexMeshDict +++ b/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/system/snappyHexMeshDict @@ -210,6 +210,12 @@ castellatedMeshControls // NOTE: This point should never be on a face, always inside a cell, even // after refinement. locationInMesh (0.01 0.01 0.01); + + + // Whether any faceZones (as specified in the refinementSurfaces) + // are only on the boundary of corresponding cellZones or also allow + // free-standing zone faces. Not used if there are no faceZones. + allowFreeStandingZoneFaces false; } diff --git a/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict b/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict index 948273e71d..1878f5b1a7 100644 --- a/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict +++ b/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict @@ -51,9 +51,9 @@ castellatedMeshControls // Refinement parameters // ~~~~~~~~~~~~~~~~~~~~~ - // While refining maximum number of cells per processor. This is basically - // the number of cells that fit on a processor. If you choose this too small - // it will do just more refinement iterations to obtain a similar mesh. + // If local number of cells is >= maxLocalCells on any processor + // switches from from refinement followed by balancing + // (current method) to (weighted) balancing before refinement. maxLocalCells 1000000; // Overall cell limit (approximately). Refinement will stop immediately @@ -69,6 +69,13 @@ castellatedMeshControls // (unless the number of cells to refine is 0) minRefinementCells 10; + // Allow a certain level of imbalance during refining + // (since balancing is quite expensive) + // Expressed as fraction of perfect balance (= overall number of cells / + // nProcs). 0=balance always. + maxLoadUnbalance 0.10; + + // Number of buffer layers between different levels. // 1 means normal 2:1 refinement restriction, larger means slower // refinement. @@ -180,6 +187,8 @@ snapControls // Settings for the layer addition. addLayersControls { + // Are the thickness parameters below relative to the undistorted + // size of the refined cell outside layer (true) or absolute sizes (false). relativeSizes true; // Per final patch (so not geometry!) the layer information @@ -466,6 +475,8 @@ addLayersControls // is the // thickness of the layer furthest away from the wall. // Relative to undistorted size of cell outside layer. + // is the thickness of the layer furthest away from the wall. + // See relativeSizes parameter. finalLayerThickness 0.3; //- Minimum thickness of cell layer. If for any reason layer @@ -539,6 +550,7 @@ meshQualityControls minFlatness 0.5; //- Minimum pyramid volume. Is absolute volume of cell pyramid. + // Set to a sensible fraction of the smallest cell volume expected. // Set to very negative number (e.g. -1E30) to disable. minVol 1e-13;