|
[Sponsors] |
[snappyHexMesh] SHM not snapping to some surfaces |
![]() |
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
![]() |
![]() |
#1 |
Member
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11 ![]() |
Greetings to the forum!
I have been attempting to mesh a mixer and mixer tank. I have defined the stl geometries and am able to snap to some of the surfaces e.g. the tank and the AMI planes to a satisfactory level. The most complex geometry is the impeller and I have tried to refine these features but am unable to get SHM to snap to the blades (rotor geometry in SHM dict file). It seems to be leaving the mesh castellated on the rotor geometry while being snapped on the other geometry and I don't know how to resolve this. I have attached a picture to show what I mean. ![]() I am quite new to SHM and CFD in general. Some of the things that I have tried but haven't seem to help are:
Here is my SHM file: Code:
/*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: 2.4.0 | | \\ / A nd | Web: www.OpenFOAM.org | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile { version 2.0; format ascii; class dictionary; object snappyHexMeshDict; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Which of the steps to run castellatedMesh true; snap true; addLayers false; // Geometry. Definition of all surfaces. All surfaces are of class // searchableSurface. // Surfaces are used // - to specify refinement for any mesh cell intersecting it // - to specify refinement for any mesh cell inside/outside/near // - to 'snap' the mesh boundary to the surface geometry { AMIbottom.stl { type triSurfaceMesh; name AMIbottom; } AMItop.stl { type triSurfaceMesh; name AMItop; } Rotorb.stl { type triSurfaceMesh; name Rotorb; } Rotort.stl { type triSurfaceMesh; name Rotort; } Shaftb.stl { type triSurfaceMesh; name Shaftb; } Shaftt.stl { type triSurfaceMesh; name Shaftt; } Tank.stl { type triSurfaceMesh; name Tank; } Baffles.stl { type triSurfaceMesh; name Baffles; } /* refinementCylinder { type searchableCylinder; point1 (0 0 0.5); point2 (0 0 1.5); radius 0.6; } */ }; // Settings for the castellatedMesh generation. castellatedMeshControls { // Refinement parameters // ~~~~~~~~~~~~~~~~~~~~~ // 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 100000; // Overall cell limit (approximately). Refinement will stop immediately // upon reaching this number so a refinement level might not complete. // Note that this is the number of cells before removing the part which // is not 'visible' from the keepPoint. The final number of cells might // actually be a lot less. maxGlobalCells 2000000; // The surface refinement loop might spend lots of iterations refining just a // few cells. This setting will cause refinement to stop if <= minimumRefine // are selected for refinement. Note: it will at least do one iteration // (unless the number of cells to refine is 0) minRefinementCells 0; // Number of buffer layers between different levels. // 1 means normal 2:1 refinement restriction, larger means slower // refinement. nCellsBetweenLevels 1; // Explicit feature edge refinement // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Specifies a level for any cell intersected by its edges. // This is a featureEdgeMesh, read from constant/triSurface for now. features ( { file "AMIbottom.extendedFeatureEdgeMesh"; level 3; } { file "AMItop.extendedFeatureEdgeMesh"; level 3 ; } { file "Rotorb.extendedFeatureEdgeMesh"; level 6; } { file "Rotort.extendedFeatureEdgeMesh"; level 6; } { file "Shaftb.extendedFeatureEdgeMesh"; level 0; } { file "Shaftt.extendedFeatureEdgeMesh"; level 0; } { file "Tank.extendedFeatureEdgeMesh"; level 3; } { file "Baffles.extendedFeatureEdgeMesh"; level 8; } ); // Surface based refinement // ~~~~~~~~~~~~~~~~~~~~~~~~ // Specifies two levels for every surface. The first is the minimum level, // every cell intersecting a surface gets refined up to the minimum level. // The second level is the maximum level. Cells that 'see' multiple // intersections where the intersections make an // angle > resolveFeatureAngle get refined up to the maximum level. refinementSurfaces { AMIbottom { level (4 4); faceType baffle; cellZone innerCylinderSmallb; faceZone innerCylinderSmallb; cellZoneInside inside; } AMItop { level (4 4); faceType baffle; cellZone innerCylinderSmallt; faceZone innerCylinderSmallt; cellZoneInside inside; } Rotorb { level (2 5); } Rotort { level (2 5); } Shaftb { level (3 4); } Shaftt { level (3 4); } Tank { level (2 2); } Baffles { level (4 5); } } resolveFeatureAngle 10; // Region-wise refinement // ~~~~~~~~~~~~~~~~~~~~~~ // Specifies refinement level for cells in relation to a surface. One of // three modes // - distance. 'levels' specifies per distance to the surface the // wanted refinement level. The distances need to be specified in // descending order. // - inside. 'levels' is only one entry and only the level is used. All // cells inside the surface get refined up to the level. The surface // needs to be closed for this to be possible. // - outside. Same but cells outside. refinementRegions { Tank { mode inside; levels ((1E15 2)); } /* refinementCylinder { mode inside; levels ((1E15 3)); } */ AMIbottom { mode inside; levels ((1E15 4)); } AMItop { mode inside; levels ((1E15 4)); } } // Mesh selection // ~~~~~~~~~~~~~~ // After refinement patches get added for all refinementSurfaces and // all cells intersecting the surfaces get put into these patches. The // section reachable from the locationInMesh is kept. // NOTE: This point should never be on a face, always inside a cell, even // after refinement. // This is an outside point locationInMesh (-0.033 -0.033 0.0033); locationInMesh (0.23149 0.054123 0.05658); // Inside point // 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; } // Settings for the snapping. snapControls { //- Number of patch smoothing iterations before finding correspondence // to surface nSmoothPatch 8; //- Relative distance for points to be attracted by surface feature point // or edge. True distance is this factor times local // maximum edge length. tolerance 1.0; //- Number of mesh displacement relaxation iterations. nSolveIter 300; //- Maximum number of snapping relaxation iterations. Should stop // before upon reaching a correct mesh. nRelaxIter 8; // Feature snapping //- Number of feature edge snapping iterations. // Leave out altogether to disable. nFeatureSnapIter 5; //- Detect (geometric) features by sampling the surface implicitFeatureSnap true; //- Use castellatedMeshControls::features explicitFeatureSnap true; //- Detect features between multiple surfaces // (only for explicitFeatureSnap, default = false) multiRegionFeatureSnap true; } // 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 layers { "flange_.*" { nSurfaceLayers 1; } } // Expansion factor for layer mesh expansionRatio 1.0; // Wanted thickness of final added cell layer. If multiple layers // is the thickness of the layer furthest away from the wall. // Relative to undistorted size of cell outside layer. // See relativeSizes parameter. finalLayerThickness 0.3; // Minimum thickness of cell layer. If for any reason layer // cannot be above minThickness do not add layer. // See relativeSizes parameter. minThickness 0.25; // If points get not extruded do nGrow layers of connected faces that are // also not grown. This helps convergence of the layer addition process // close to features. nGrow 0; // Advanced settings // When not to extrude surface. 0 is flat surface, 90 is when two faces // are perpendicular featureAngle 30; // Maximum number of snapping relaxation iterations. Should stop // before upon reaching a correct mesh. nRelaxIter 5; // Number of smoothing iterations of surface normals nSmoothSurfaceNormals 1; // Number of smoothing iterations of interior mesh movement direction nSmoothNormals 3; // Smooth layer thickness over surface patches nSmoothThickness 10; // Stop layer growth on highly warped cells maxFaceThicknessRatio 0.5; // Reduce layer growth where ratio thickness to medial // distance is large maxThicknessToMedialRatio 0.3; // Angle used to pick up medial axis points minMedianAxisAngle 90; // Create buffer region for new layer terminations nBufferCellsNoExtrude 0; // 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; // Max number of iterations after which relaxed meshQuality controls // get used. Up to nRelaxIter it uses the settings in meshQualityControls, // after nRelaxIter it uses the values in meshQualityControls::relaxed. nRelaxedIter 20; } // Generic mesh quality settings. At any undoable phase these determine // where to undo. meshQualityControls { //- Maximum non-orthogonality allowed. Set to 180 to disable. maxNonOrtho 65; //- Max skewness allowed. Set to <0 to disable. maxBoundarySkewness 20; maxInternalSkewness 4; //- Max concaveness allowed. Is angle (in degrees) below which concavity // is allowed. 0 is straight face, <0 would be convex face. // Set to 180 to disable. maxConcave 80; //- 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; //- Minimum quality of the tet formed by the face-centre // and variable base point minimum decomposition triangles and // the cell centre. This has to be a positive number for tracking // to work. Set to very negative number (e.g. -1E30) to // disable. // <0 = inside out tet, // 0 = flat tet // 1 = regular tet minTetQuality 1e-15;//-1E30; //1e-15; //- Minimum face area. Set to <0 to disable. minArea -1; //- Minimum face twist. Set to <-1 to disable. dot product of face normal // and face centre triangles normal minTwist 0.02; //- Minimum normalised cell determinant. This is the determinant of all // the areas of internal faces. It is a measure of how much of the // outside area of the cell is to other cells. The idea is that if all // outside faces of the cell are 'floating' (zeroGradient) the // 'fixedness' of the cell is determined by the area of the internal faces. // 1 = hex, <= 0 = folded or flattened illegal cell minDeterminant 0.001; //- Relative position of face in relation to cell centres (0.5 for orthogonal // mesh) (0 -> 0.5) minFaceWeight 0.05; //- Volume ratio of neighbouring cells (0 -> 1) minVolRatio 0.01; //- Per triangle normal compared to average normal. Like face twist // but now per (face-centre decomposition) triangle. Must be >0 for Fluent // compatibility minTriangleTwist -1; //- if >0 : preserve cells with all points on the surface if the // resulting volume after snapping (by approximation) is larger than // minVolCollapseRatio times old volume (i.e. not collapsed to flat cell). // If <0 : delete always. //minVolCollapseRatio 0.1; // Optional : some meshing phases allow usage of relaxed rules. // See e.g. addLayersControls::nRelaxedIter. relaxed { //- Maximum non-orthogonality allowed. Set to 180 to disable. maxNonOrtho 75; } // Advanced //- Number of error distribution iterations nSmoothScale 4; //- amount to scale back displacement at error points errorReduction 0.75; } // Advanced // Write flags writeFlags ( scalarLevels // write volScalarField with cellLevel for postprocessing layerSets // write cellSets, faceSets of faces in layer layerFields // write volScalarField for layer coverage ); // Merge tolerance. Is fraction of overall bounding box of initial mesh. // Note: the write tolerance needs to be higher than this. mergeTolerance 1E-6; // ************************************************************************* // Code:
// How to obtain raw features (extractFromFile || extractFromSurface) extractionMethod extractFromSurface; extractFromSurfaceCoeffs { // Mark edges whose adjacent surface normals are at an angle less // than includedAngle as features // - 0 : selects no edges // - 180: selects all edges includedAngle 150; } trimFeatures { // Remove features with fewer than the specified number of edges minElem 5; Regards, Thomas Last edited by wyldckat; November 7, 2015 at 09:18. Reason: removed broken image links |
|
![]() |
![]() |
![]() |
![]() |
#2 |
Retired Super Moderator
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,978
Blog Entries: 45
Rep Power: 128 ![]() ![]() ![]() ![]() ![]() ![]() |
Quick answer:
|
|
![]() |
![]() |
![]() |
![]() |
#3 |
Member
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11 ![]() |
Hi Bruno,
Thanks for your reply. I realise without the test case that it will be hard to diagnose the problem. I will put together a simplified case on Monday that I hope will show my problem and post it then. In the meantime I have increased the maxLocalCells and maxGlobalCells to see if that changes the results. I definitely did not even think of changing these variables. Thanks again for answering. Thomas |
|
![]() |
![]() |
![]() |
![]() |
#4 |
Member
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11 ![]() |
Hi again Bruno,
I have uploaded a simplified case. The link is as follows: https://drive.google.com/folderview?...Fk&usp=sharing I have used the same tank stl file that I was originally using and as you will see I have saved to to a high resolution so it is quite big. The main concern is the rotor which you will see for some reason remains castellated. I appreciate your help looking at this. Regards, Thomas |
|
![]() |
![]() |
![]() |
![]() |
#5 |
Retired Super Moderator
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,978
Blog Entries: 45
Rep Power: 128 ![]() ![]() ![]() ![]() ![]() ![]() |
Hi Thomas,
Took me a bit to understand where the problem was, since you had mentioned a tank in the latest post and the problem was on the rotor ![]() First, two important references:
Best regards, Bruno |
|
![]() |
![]() |
![]() |
![]() |
#6 | |||
Member
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11 ![]() |
Hi Bruno,
Quote:
Quote:
4.1 - I noticed a problem with the Geometry.png file. It appears that there is no surface at the end of the impeller. See my marked up Geometry.png file. Maybe this is a cause for my problems! I recreated the geometry in Autodesk and saved it to an stl file, ensuring that I could see this surface. I have uploaded this image as "geometry-Improved.png". You will notice that I have also changed the thickness of the impeller to make it easier for SHM to snap. I think this is an acceptable change as I am more interested in the flow in the rest of the tank as opposed to the flow over the rotor. 4.2 - Yes I see the grid is too stepped. Quote:
Code:
Rotorb { // Surface-wise min and max refinement level level (7 7); //- Optional increment (on top of max level) in small gaps gapLevelIncrement 1; } 2 - 3) I was slowly starting to realise that this was the problem but was hoping that there would be a way to resolve this. In fact it is the reason that I have high refinement on the edges of the rotor. I have tried to increase the surface refinement to see if I get a better mesh. Should I also change the "tolerance value"? Ideally I don't want to have to refine around the rotor too much as this increases the solving time. As I mentioned above, I will thicken the rotor in addition to refining the mesh to make it easier for snappyHexMesh. I think this combination should help get the balance between a refined mesh and and easier mesh for SHM to snap to. 4) I have rerun SHM with a thicker rotor (but without gapLevelIncrement included as I still need totest it) and a more refined mesh. I also tested increasing the resolution of the blockMesh grid, but so far nothing seems to have helped. I do not understand the comment that if after refinement, the mesh does not snap to the stl, then it is not being seen by SHM because SHM has been refining around the stl to produce the castellated steps. Why would it then not see the stl in the snapping step? With the thicker rotor with the closed end, the more refined blockMesh and increased surface and feature refinement levels, I still seem to have the same problem of the mesh not snapping to the surface. See the files Geometry-Castellated.png and Geometry-snapStep.png. Do you have any other suggestions as to what I should try? Kind regards, Thomas |
||||
![]() |
![]() |
![]() |
![]() |
#7 |
Member
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11 ![]() |
Hi,
I forgot to post the link to the updated case. Here is the link: https://drive.google.com/folderview?...0E&usp=sharing Regards, Thomas |
|
![]() |
![]() |
![]() |
![]() |
#8 |
Member
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11 ![]() |
Hi All,
I have made some progress in trying to identify and solve the problem. I increased these parameters by 20x but still my rotor did not mesh. In particular the blades were not meshing but the hub was. maxLocalCells 100000; maxGlobalCells 2000000; Two meshing tests showed me that it was not the stl surface that was the problem. I proved this by doing the following:
This proved a few things to me:
I suspect that the problem that the rotor is not being snapped is because perhaps the rotor geometry is small in relation to the tank. I don't know how SHM works well enough to be able to confirm/verify this however. It seems to me that perhaps it has something to do with the tolerance value. Perhaps someone on the forum has an explanation/solution that will allow me to mesh the entire geometry in one step? In terms of resolving the problem, I think I will have to generate the mesh in a series of steps as described in this tutorial: http://www.sourceflux.de/blog/genera...snappyhexmesh/. Essentially, I will using the same blockMeshDict and settings from snappHexMeshDict, generate a mesh for the rotor contained within the AMI volume and a separate mesh for the tank with the AMI volume cut out and then merge and stitch the meshes at the common AMI plane. Then I will use setSet to define the cellZone which will define the rotating volume. I will want to have two rotors rotating in the tank and will therefore have to do several steps, so it will be a somewhat cumbersome process. Does this approach sound reasonable or does anybody have any suggestions that would make my life easier? Best regards, Thomas |
|
![]() |
![]() |
![]() |
![]() |
#9 |
Retired Super Moderator
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,978
Blog Entries: 45
Rep Power: 128 ![]() ![]() ![]() ![]() ![]() ![]() |
Hi Thomas,
I've taken a look at the latest case you shared and I'm not certain of what is going on wrong. The first problem is that there are way too many warnings and it's not easy enough to pinpoint which warning relates to what. My guess is that snappyHexMesh isn't able to snap the mesh surfaces onto the rotor blades, without severely distorting the mesh, which would result in a very low quality mesh. My advice: isolate and conquer. The main issue is on the rotor, but only the blades. Problem is that there are a ton of warnings related to the outer tank surface. Therefore, try to mesh only one of the blades. In addition, reduce the base mesh to make it closer to the blade, so that it can mesh faster. As for "tolerance", this is mostly a trial and error issue. This parameter can assist you in making mesh points that are really far away be attracted to a surface. For example, if the tolerance is set to "10.0", this means that a point that is 10 times farther away than it's current cell edge length (of the current refined mesh), can be attracted to the closest "10x edge length" surface.
Beyond this, use "nSmoothPatch" with caution. I haven't had good experiences with this parameter, but that might be due to the geometries I've been using. The other trick is to use the debug flags. Example provided here: https://github.com/OpenFOAM/OpenFOAM...ppyHexMeshDict Code:
//// Debug flags //debugFlags //( // mesh // write intermediate meshes // intersections // write current mesh intersections as .obj files // featureSeeds // write information about explicit feature edge // // refinement // attraction // write attraction as .obj files // layerInfo // write information about layers //); For "gapLevelIncrement", you can find information here: https://github.com/OpenFOAM/OpenFOAM...ppyHexMeshDict The "detectNearSurfacesSnap" parameter is set to "true" by default, as shown here: https://github.com/OpenFOAM/OpenFOAM...apParameters.C - In addition, this settings is meant to be defined inside the block "snapControls". And remember: isolate and conquer. Best regards, Bruno |
|
![]() |
![]() |
![]() |
![]() |
#10 |
Member
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11 ![]() |
Hi Bruno,
Thanks for your reply and once again, the links that you included. They are very useful. I had already done as you suggested, that is, to divide and conquer. These are my steps:
In short I have not managed to find a solution to my problem, but I did manage to find a workaround. Again, thanks for your help Bruno! Thomas Last edited by wyldckat; November 21, 2015 at 14:51. Reason: fixed broken link |
|
![]() |
![]() |
![]() |
![]() |
#11 |
Retired Super Moderator
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,978
Blog Entries: 45
Rep Power: 128 ![]() ![]() ![]() ![]() ![]() ![]() |
Hi Thomas,
I'm glad you've managed to get a working workaround for this! And for sharing the solution that you've reached! Meshing everything in a single go requires using the faceZone+cellZone feature that snappyHexMesh has got. The downside of this is that the algorithm gets a bit confused on how to move points near a ghost-like surface that a faceZone essentially is, because it has to snap cell vertexes from both sides, without loosing mesh cohesion on the common surface. Although this doesn't explain why the mesh around the rotor was acting up... When you mesh the two sides of the mesh individually, are you using the same exact base mesh? Or have you configured a dedicated base mesh for each part? Best regards, Bruno |
|
![]() |
![]() |
![]() |
![]() |
#12 | ||
Member
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11 ![]() |
Hi Bruno,
Quote:
Quote:
Best regards, Thomas |
|||
![]() |
![]() |
![]() |
![]() |
#13 | ||
Retired Super Moderator
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,978
Blog Entries: 45
Rep Power: 128 ![]() ![]() ![]() ![]() ![]() ![]() |
Hi Thomas,
Quote:
Quote:
I won't be able to do any more tests before the end of the week, but there is something that came to mind and I can't quickly find on the previous posts: Are you running snappyHexMesh in parallel? Because I recently found out about a problem that sometimes occurs when meshing with faceZones in parallel: http://www.cfd-online.com/Forums/ope...tml#post575690 - post #10. Best regards, Bruno |
|||
![]() |
![]() |
![]() |
![]() |
#14 | |
Member
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11 ![]() |
Greetings Bruno,
Compliments of the season to you. Sorry it has been so long since your last post without me replying. I have been carrying on with my mesh with the method of meshing the rotor and stator parts of the domain separately as I had previously described. Quote:
I think that part of my problem could be resolved by refining the mesh further. Unfortunately, I don't want to do this as then the time to solve becomes too long. Although I will lose some information about the flow around the rotor, I am more interested in the bulk flow in the tank and in these regions the flow is pretty slow and a less refined mesh is suitable. Meshing the stator and rotor domains separately allows me to use a coarser mesh. I will do mesh independence checks just to make sure that I am comfortable with the solutions I am obtaining. Thanks for your help. It has really been greatly appreciated! Regards, Thomas |
||
![]() |
![]() |
![]() |
|
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
[snappyHexMesh] SHM not snapping on simple case | slaners | OpenFOAM Meshing & Mesh Conversion | 7 | June 6, 2018 06:43 |
[snappyHexMesh] SHM doesn't create cellZones for one region | Eko | OpenFOAM Meshing & Mesh Conversion | 10 | January 24, 2018 02:03 |
[snappyHexMesh] SHM Problems with snapping and layers | Rojj | OpenFOAM Meshing & Mesh Conversion | 0 | April 14, 2016 13:52 |
[snappyHexMesh] Can't couple front & back faces in cyclic BC after snapping in SHM | hakonbar | OpenFOAM Meshing & Mesh Conversion | 4 | December 8, 2013 16:50 |
[snappyHexMesh] SHM: feature edge snapping not conforming | thab | OpenFOAM Meshing & Mesh Conversion | 3 | November 26, 2012 14:04 |