CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Meshing & Mesh Conversion

[snappyHexMesh] Rough leading-edge and trailing-edge after snapping

Register Blogs Community New Posts Updated Threads Search

Like Tree13Likes
  • 5 Post By Yann
  • 2 Post By gabrielfelix
  • 1 Post By gabrielfelix
  • 4 Post By gabrielfelix
  • 1 Post By gabrielfelix

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   September 15, 2021, 15:29
Default Rough leading-edge and trailing-edge after snapping
  #1
Member
 
Gabriel Felix
Join Date: May 2021
Location: Brazil
Posts: 35
Rep Power: 6
gabrielfelix is on a distinguished road
Hi folks,

I'm running a propeller case and I'm getting a rough mesh discretization on the body near the trailing-edge and leading-edge. Surface is bumpy and prismatic on these regions.

Even using featureEdge refinement level 9, and refinementSurfaces level (9 10) i can't improve the rough leading- and trailing-edge. I have already tried to tune all the snapControls parameters without any success.

The leading-edge and trailing-edge still rough. The leading-edge discretization is poor and more refinement is needed on this region, since the curvature is been represented as straight lines with some kinks (this highly affects pressure distribution on the region). The snappyHexMesh fails to snap the mesh in this regions. SHM also seems to fail when adding layers on these regions as well.

I don't know what to do anymore. I was even thinking on user another mesh program. I've already tried:
- Using a higher quality .stl
- Increasing or decreasing refinement levels in featureEdge, refinementSurface
- Changed nCellsBetweenLevels
- Switched from implicitFeatureSnap to explicitFeatureSnap (improved a little)
- Changed snap tolerance. Below 1.0 it worsen the mesh an above 1.0 it has no apparent effect
- Tune every snapControls parameters
- Changed meshQualityControls parameters
- Changed minTetQuality to -1e30 (improved a little)
- etc

Below are some images, the link to download the case, snappyHexMeshDict and checkMesh output.

Images 1 and 2 are the resultant solid after meshing
Images 7 and 8 are the internal mesh slice
Image 9 is the stl file

My case is available here if anyone wants to try running it: https://drive.google.com/file/d/1xdq...ew?usp=sharing
I suggest you to use the Allrun scripts.

My snappyHexMeshDict:

Code:
/*--------------------------------*- C++ -*----------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  v2012                                 |
|   \\  /    A nd           | Website:  www.openfoam.com                      |
|    \\/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    object      snappyHexMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

// Which of the steps to run
castellatedMesh true;
snap            true;
addLayers       true;


// 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
{
    innerCylinderSmall.stl
	{
		type triSurfaceMesh; 
		name innerCylinderSmall;
	}
	
	//innerCylinder.stl
	//{
	//	type triSurfaceMesh; 
	//	name innerCylinder;
	//}
	outerCylinder.stl
	{
		type triSurfaceMesh; 
		name outerCylinder;
	}
	propellerTip.stl
	{
		type triSurfaceMesh; 
		name propellerTip;
	}
}


// 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 500000;

    // 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 5000000;

    // 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;

    // 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.
    nCellsBetweenLevels 3;



    // 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        "innerCylinderSmall.eMesh";
            level       5;
        }
        {
            file        "outerCylinder.eMesh";
            level       0;
        }
        {
            file        "propellerTip.eMesh";
            level       9;
        }
    );



    // 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
    {
        innerCylinderSmall
        {
            level       (5 5);

            faceType    boundary;
            cellZone    innerCylinderSmall;
            faceZone    innerCylinderSmall;
            cellZoneInside  inside;
        }
        outerCylinder
        {
            level       (0 0);
        }
        propellerTip
        {
            level       (9 10);
        }
    }

    // Resolve sharp angles
    resolveFeatureAngle 30;


    // 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
    {
        //innerCylinder
        //{
        //    mode        inside;
        //    levels      ((1E15 5));
        //}
        innerCylinderSmall
        {
            mode        inside;
            levels      ((1E15 6));
        }
    }


    // 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.
    locationInMesh (0.01 -1.5 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;
}



// Settings for the snapping.
snapControls
{
    //- Number of patch smoothing iterations before finding correspondence
    //  to surface
    nSmoothPatch 3;

    //- 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; // 1.0;

    //- Number of mesh displacement relaxation iterations.
    nSolveIter 150;

    //- Maximum number of snapping relaxation iterations. Should stop
    //  before upon reaching a correct mesh.
    nRelaxIter 5;

    // Feature snapping

        // Number of feature edge snapping iterations.
        // Leave out altogether to disable.
        nFeatureSnapIter 30;

        // Detect (geometric only) features by sampling the surface
        // (default=false).
        implicitFeatureSnap true;

        // Use castellatedMeshControls::features (default = true)
        explicitFeatureSnap false;

        // 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
    {
		"propellerTip.*"
			{
				nSurfaceLayers 3;
			}
    }

    // 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.
    // Relative to undistorted size of cell outside layer.
    minThickness 0.1;

    // 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.
    // Note: changed(corrected) w.r.t 1.7.x! (didn't do anything in 1.7.x)
    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
    // Note: changed(corrected) w.r.t 1.7.x! 90 degrees corresponds to 130
    // in 1.7.x.
    minMedialAxisAngle 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;
}



// 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 4;
    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
    //  to work. Set to very negative number (e.g. -1E30) to
    //  disable.
    //     <0 = inside out tet,
    //      0 = flat tet
    //      1 = regular tet
    minTetQuality -1e30; // 1e-30;

    //- 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.01;

    //- Minimum normalised cell determinant
    //  1 = hex, <= 0 = folded or flattened illegal cell
    minDeterminant 0.001;

    //- minFaceWeight (0 -> 0.5)
    minFaceWeight 0.05;

    //- minVolRatio (0 -> 1)
    minVolRatio 0.01;

    //must be >0 for Fluent compatibility
    minTriangleTwist -1;


    // Advanced

    //- Number of error distribution iterations
    nSmoothScale 4;
    //- Amount to scale back displacement at error points
    errorReduction 0.75;

    // 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;
    }
}



// Merge tolerance. Is fraction of overall bounding box of initial mesh.
// Note: the write tolerance needs to be higher than this.
mergeTolerance 1e-6;


// ************************************************************************* //
checkMesh output

Code:
$ checkMesh
/*---------------------------------------------------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  v2012                                 |
|   \\  /    A nd           | Website:  www.openfoam.com                      |
|    \\/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
Build  : _7bdb509494-20201222 OPENFOAM=2012
Arch   : "LSB;label=32;scalar=64"
Exec   : checkMesh
Date   : Sep 15 2021
Time   : 15:19:22
Host   : MSI
PID    : 12237
I/O    : uncollated
Case   : /mnt/c/Users/Felix/Documents/Mestrado/OpenFOAM/runs/mscPropeller/18mscSalomeAs14Compressible9-10newConfigsLayer
nProcs : 1
trapFpe: Floating point exception trapping enabled (FOAM_SIGFPE).
fileModificationChecking : Monitoring run-time modified files using timeStampMaster (fileModificationSkew 5, maxFileModificationPolls 20)
allowSystemOperations : Allowing user-supplied system call operations

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Create time

Create mesh for time = 0

Time = 0

Mesh stats
    points:           1451811
    faces:            3794952
    internal faces:   3591866
    cells:            1178648
    faces per cell:   6.2672
    boundary patches: 6
    point zones:      0
    face zones:       1
    cell zones:       1

Overall number of cells of each type:
    hexahedra:     958645
    prisms:        32238
    wedges:        0
    pyramids:      0
    tet wedges:    224
    tetrahedra:    0
    polyhedra:     187541
    Breakdown of polyhedra by number of faces:
        faces   number of cells
            4   11178
            5   9382
            6   26385
            7   51150
            8   13158
            9   56525
           10   160
           11   60
           12   14972
           13   2
           14   32
           15   4387
           17   12
           18   138

Checking topology...
    Boundary definition OK.
    Cell to face addressing OK.
    Point usage OK.
    Upper triangular ordering OK.
    Face vertices OK.
   *Number of regions: 2
    The mesh has multiple regions which are not connected by any face.
  <<Writing region information to "0/cellToRegion"
  <<Writing region 0 with 64413 cells to cellSet region0
  <<Writing region 1 with 1114235 cells to cellSet region1

Checking patch topology for multiply connected surfaces...
                   Patch    Faces   Points                  Surface topology
           outerCylinder      288      388  ok (non-closed singly connected)
            propellerTip   161714   174976      ok (closed singly connected)
                    AMI1    20180    20350      ok (closed singly connected)
                    AMI2    20720    20834      ok (closed singly connected)
                   inlet      140      169  ok (non-closed singly connected)
                  outlet       44       49  ok (non-closed singly connected)

Checking faceZone topology for multiply connected surfaces...
                FaceZone    Faces   Points                  Surface topology
      innerCylinderSmall    40900    41184      ok (closed singly connected)

Checking basic cellZone addressing...
                CellZone        Cells       Points       VolumeBoundingBox
     innerCylinderSmall      1114235      1362647     0.297655 (-0.4375 -0.175161 -0.4375) (0.4375 0.325212 0.4375)

Checking geometry...
    Overall domain bounding box (-1.04998 -2.45 -1.04998) (1.04998 1.05057 1.04998)
    Mesh has 3 geometric (non-empty/wedge) directions (1 1 1)
    Mesh has 3 solution (non-empty) directions (1 1 1)
    Boundary openness (2.11947e-18 2.03185e-17 -3.89911e-18) OK.
    Max cell openness = 4.22748e-16 OK.
    Max aspect ratio = 24.4339 OK.
    Minimum face area = 5.38589e-09. Maximum face area = 0.245378.  Face area magnitudes OK.
    Min volume = 1.83686e-12. Max volume = 0.069149.  Total volume = 11.9942.  Cell volumes OK.
    Mesh non-orthogonality Max: 64.9066 average: 12.5906
    Non-orthogonality check OK.
    Face pyramids OK.
    Max skewness = 3.98566 OK.
    Coupled point location match (average 0) OK.

Mesh OK.

End
Attached Images
File Type: jpg Imagem1.jpg (25.0 KB, 180 views)
File Type: png Imagem2.png (122.8 KB, 156 views)
File Type: jpg Imagem7.jpg (126.6 KB, 201 views)
File Type: jpg Imagem8.jpg (148.0 KB, 180 views)
File Type: png Imagem9.png (81.6 KB, 125 views)

Last edited by gabrielfelix; September 16, 2021 at 08:57.
gabrielfelix is offline   Reply With Quote

Old   September 16, 2021, 04:16
Default
  #2
Senior Member
 
Yann
Join Date: Apr 2012
Location: France
Posts: 1,238
Rep Power: 29
Yann will become famous soon enoughYann will become famous soon enough
Hi Gabriel,

Here are my first thoughts:
  • Use explicitFeatureSnap true in order to take advantage of the feature edge refinement. It should help with your trailing edge and airfoil tip
  • To improve the mesh on your leading edge, you have to increase the max refinement level in refinement surfaces. In your case, the refinementSurfaces on your propellerTip is defined to level (9 10). This is what snappy does, but as you can see on your screenshot, level 10 on the leading edge is not enough to get a smooth edge.
  • Your trailing edge is very thin. You have to pick the appropriate refinement level to match the trailing edge thickness if you want to have a clean mesh
  • Your blockMesh has an aspect ration of 2.4. I understand this is meant to get a lighter mesh but keep in mind snappy will usually do a better job with an aspect ratio close to 1 on the initial mesh.
I hope this helps,
Yann
esma, AtoHM, hogsonik and 2 others like this.

Last edited by Yann; September 16, 2021 at 07:01.
Yann is offline   Reply With Quote

Old   September 16, 2021, 10:10
Default
  #3
Member
 
Gabriel Felix
Join Date: May 2021
Location: Brazil
Posts: 35
Rep Power: 6
gabrielfelix is on a distinguished road
Hey Yann,

So I followed your tips and managed to improve the mesh. Here's what I did:
  • [1] I used explicitFeatureSnap true. Which I had been previously using.
    [2] Increased refinementSurfaces level to (10 11). Which improved the leading-edge and specially the trailing-edge as well as propeller tip discretization. Nevertheless, there is still progress to be made as you can see in the figures.

    However SHM took 3x more time to run (3500 seconds). Now I'm running SHM with refinementSurfaces level to (11 12), however, I needed to further increase the upper refinement level to 12 because the LE was still rough and without layers, but I'm not sure if I should had increased the lower level as well as I did from 9 to 10, and now from 10 to 11. When I do this, I'm dramatically increasing the whole mesh domain refinement, including in regions where more refinement is not necessary. My question is: should I configure the level for exemple as (8 12) to account for this and not increase the number of cells in unecessary regions?
    [3] When I was drawing the loft I kept a finite trailing-edge because I had known previously that a sharp trailing-edge would be an issue for CFD. Still, I might have to increase the TE thickness to improve the mesh on this region.
    [4] My blockMesh aspect ratio is such because I had the need to model the propeller wake flowfield, and also because many articles and papers suggested using such such relative dimensions (based on prop diameter) for the cilindrical domain. However I'll try other aspect ratios and see what effects it will have on the mesh and solver results.

For those who didn't know the mean of the refinementSurfaces levels. I researched, and got from CFDSupport the following explanation:

Quote:
refinementSurface level sets up the number of subdivisions (halvings) of the original mesh generated by blockMesh (in our case it is our car model - car).
The degree of the subdivision is specified by level (a b), which sets the minimal (a) and maximal (b) number of cell halvings of the original blockMesh mesh. For example, if level (1 2) is specified for some surface, the adjacent cells will be subdivided once or twice, depending on the local curvature of the surface.
As the curvature of the surface rises, also the subdivision level of cells adjacent to the surface is being chosen nearer to its available maximum.
I initially thought that the levels were qualitative like in a scale from 0 to 10. That's why I had had not tried to increase the levels to numbers greater than 10. The levels are actually the number of cell halvings that occur on the region after the blockMesh set up.
Attached Images
File Type: jpg Imagem1.jpg (111.4 KB, 167 views)
File Type: jpg Imagem2.jpg (157.6 KB, 175 views)
File Type: png Imagem3.png (136.2 KB, 117 views)
File Type: png Imagem4.png (112.1 KB, 115 views)
esma and hogsonik like this.

Last edited by gabrielfelix; September 16, 2021 at 14:40.
gabrielfelix is offline   Reply With Quote

Old   September 16, 2021, 11:42
Default
  #4
Senior Member
 
Yann
Join Date: Apr 2012
Location: France
Posts: 1,238
Rep Power: 29
Yann will become famous soon enoughYann will become famous soon enough
Hi Gabriel,

Glad to see you are on your way to improve your mesh!

Quote:
Originally Posted by gabrielfelix View Post
My question is: should I configure the level for exemple as (8 12) to account for this and not increase the number of cells in unecessary regions?
Yes, you can do this and let snappy deal with the refinement level according to the curvature of your geometry.

However, it might bring other issues: snappy often struggle to extrude layers on transitions between refinement levels. With bigger gap between the min and max refinement levels (e.g. (8 12)), you will also more refinement transitions zones hence more reasons for snappy to not extrude layers.

A workaround could be to separate the leading edge, trailing edge and upper/lower surfaces of your airfoil in order to define specific refinement levels for each parts.

Quote:
Originally Posted by gabrielfelix View Post
[3] When I was drawing the loft I kept a finite trailing-edge because I had known previously that a sharp trailing-edge would be an issue for CFD. Still, I might have to increase the TE thickness to improve the mesh on this region.
This is a good thing to do, and you are right, you need to adjust your TE thickness to the mesh resolution you aim to get.

Quote:
Originally Posted by gabrielfelix View Post
[4] My blockMesh aspect ratio is such because I had the need to model the propeller wake flowfield, and also because many articles and papers suggested using such such relative dimensions (based on prop diameter) for the cilindrical domain. However I'll try other aspect ratios and see what effects it will have on the mesh and solver results.
You can mix both: in your blockMeshDict, you can define a block with aspect ratio 1 around your propeller tip and other blocks upstream and downstream with the aspect ratio you want. And you can use grading on these blocks to achieve a smooth transition between blocks.


Cheers,
Yann
Yann is offline   Reply With Quote

Old   September 16, 2021, 16:17
Default
  #5
Member
 
Gabriel Felix
Join Date: May 2021
Location: Brazil
Posts: 35
Rep Power: 6
gabrielfelix is on a distinguished road
Quote:
Originally Posted by Yann View Post
However, it might bring other issues: snappy often struggle to extrude layers on transitions between refinement levels. With bigger gap between the min and max refinement levels (e.g. (8 12)), you will also more refinement transitions zones hence more reasons for snappy to not extrude layers.
You're right. I ran levels (8 12) and, although it didn't take so long to run, results were poorer than levels (10 11). The leading-edge was smoother, but SHM failed to add layers on it as well as on the regions near trailing-edge. I'm still running other tests ((7 14) and (11-12))) which are taking nearly 5 hours already. The big gap between levels is indeed an issue. I'll keep trying to find the best setup, and I'll reach out again if I have good news.

I'm also getting a very large number of faces with face pyramid volume < 1e-13. 7496109 is pretty much the same number of my whole mesh cells. I think this is one of the reasons that SHM is taking so long to run.

Code:
Checking mesh with layer ...
Checking faces in error :
    non-orthogonality > 65  degrees                        : 114
    faces with face pyramid volume < 1e-13                 : 7496109
    faces with concavity > 80  degrees                     : 0
    faces with skewness > 4   (internal) or 4   (boundary) : 0
    faces with interpolation weights (0..1)  < 0.05        : 1326
    faces with volume ratio of neighbour cells < 0.01      : 2
    faces with face twist < 0.01                           : 38
    faces on cells with determinant < 0.001                : 0
Detected 7497589 illegal faces (concave, zero area or negative cell pyramid volume)
Extruding 212139 out of 2157951 faces (9.83058%). Removed extrusion at 13521 faces.
Added 629266 out of 6473853 cells (9.72012%).
Quote:
Originally Posted by Yann View Post
You can mix both: in your blockMeshDict, you can define a block with aspect ratio 1 around your propeller tip and other blocks upstream and downstream with the aspect ratio you want. And you can use grading on these blocks to achieve a smooth transition between blocks.
I got what you said, but I don't know how to do this yet. I didn't know that you could use multiple blocks on blockMesh. I thought that the one block mesh should contain the whole simulation domain. I'll research more about it and explore this posssibility later.

I'll also separate the spinner and propeller inside the stl file to better control the refinement of the mesh around them. My mesh is becoming increasingly finer and the drawback is that I'm getting a finer mesh where I don't need it (on the spinner for exemple). Even my university cluster is strugling to run SHM on this high refinement levels, anything I can do to decrease cell number will be helpful.

I really appreciate your help and support Yann! Your thoughts were immensely helpful to me. I was stuck on this rough mesh for a long time and your tips readily improved the mesh. Thanks for dedicating some of your time on helping the CFD community.
Yann likes this.
gabrielfelix is offline   Reply With Quote

Old   October 21, 2021, 10:41
Default
  #6
Member
 
Gabriel Felix
Join Date: May 2021
Location: Brazil
Posts: 35
Rep Power: 6
gabrielfelix is on a distinguished road
I would like to give some updates on the improvements I have had in my mesh after following some of the tips given here, specially by Yann.
  1. Modify blockMesh to aspect ratio 1: This was a milestone in my meshes.
    My mesh is composed by: the propeller, a small cylinder around it that I use as a moving mesh for MRF and AMI techniques, and an outer cylinder that encompass them as well as a small region upstream and a large region downstream to model the propeller slipstream.

    I had been using a rectangular block with AR~=1 in my blockMesh in order to wrap my outer propeller cylinder domain. When I changed the block dimensions so the aspect ratio was 1, it dramatically improved the mesh. It did it in such a way that I don't need to use surface refinement level as high as 12. SHM does the same job with levels 9 or 10. Level 2 does the same job as level 6 did on internalMesh. Not to mention the decrease on SHM exectution time from 3000+ sec to less then 1000 sec.

    Another thing that I observed is that I succesfully used greater gaps between surface refinement levels, for exemple (1 10) on the blade and (1 6) on spinner, and it worked really well. It prevented unnecessary refinement on low curvature regions and focused on higher curvature ones, such as leading-edge and trailing-edge. It decreased the global cell number and improved the mesh as a whole.
  2. resolveFeatureAngle: it was another great improvement in the mesh. My default resolveFeatureAngle was 30 and it was the main parameter responsible for the rough leading-edge. After I reduced it to 5.0, 1.0, or even less, it the LE became smoother and more discretized, as well as it helped SHM on adding boundary layers. This file: Mesh generation with snappyHexMesh by Wolf Dynamics greatly helped me better understand SHM and the meshing parameters.
  3. Separate blade from spinner: the spinner and propeller blades were contained under a single geometry file. I wanted to separate them in two files so I could better control the meshing refinement levels on each of them, and it worked perfectly. I have used lower levels on the spinner and higher levels on the blades, which decreased the global cell number and improved the meshing on both surfaces.

    So if you have a geometry with multiple regions you should split them to improve the mesh. You can either do this by creating a separate .stl file for each region, or separate and keep them under a single .stl file as multiple solids. Both approches work, but I found the first option easier and faster to apply to my simulation structure.
  4. Explicit method in snap: The explicitFeatureSnap flag uses the feature edges refinement configs to mesh around the feature edges and the regions near them. Conversely, the implicitFeatureSnap detects and refines the edge region automatically. Depending on your geometry the explicit can improve the mesh as it did in mine slightly.
  5. nCellsBetweenLevels: If your surfaceRefinement levels are as high as above 8, there will be a great gap between your surface refinement and the courser internalMesh. Increasing nCellsBetweenLevels iteratively above 2 or 3 might help on the transition between levels. However, keep in mind that it will certainly increase your cell number as it has effect on the whole mesh domain. If you dont want to affect the whole domain, you can do this by setting up the region-wise refinement on refinementRegions section. This is better detailed here: [snappyHexMesh] SnappyHexMesh boundary refinement #post 8.

Below are the new blockMesh and snappyHexMesh configs.
blcokMeshDict
Code:
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    object      blockMeshDict;
}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

scale   1;
convertToMeters   1;

vertices
(
    (-2.50 -2.50 -2.50)
    ( 2.50 -2.50 -2.50)
    ( 2.50  2.50 -2.50)
    (-2.50  2.50 -2.50)
    (-2.50 -2.50  2.50)
    ( 2.50 -2.50  2.50)
    ( 2.50  2.50  2.50)
    (-2.50  2.50  2.50)
);


blocks
(
    hex (0 1 2 3 4 5 6 7) (12 20 12) simpleGrading (1 1 1)
);

edges
(
);

boundary
(
    walls
    {
        type wall;
        faces
        (
            (2 6 5 1)
            (0 3 2 1)
            (0 4 7 3)
            (4 5 6 7)
        );
    }
    inlet
    {
        type patch;
        faces
        (
            (3 7 6 2)
        );
    }
    outlet
    {
        type patch;
        faces
        (
            (1 5 4 0)
        );
    }
);

// ************************************************************************* //
snappyHexMeshDict
Code:
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    object      snappyHexMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

// Which of the steps to run
castellatedMesh true;
snap            true;
addLayers       true;


// 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
{
    innerCylinderSmall.stl
	{
		type triSurfaceMesh; 
		name innerCylinderSmall;
	}
	
	//innerCylinder.stl
	//{
	//	type triSurfaceMesh; 
	//	name innerCylinder;
	//}
	outerCylinder.stl
	{
		type triSurfaceMesh; 
		name outerCylinder;
	}
	propellerTip.stl
	{
		type triSurfaceMesh; 
		name propellerTip;
	}
    propellerSpinner.stl
	{
		type triSurfaceMesh; 
		name propellerSpinner;
	}
}


// 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 1000000;

    // 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 10000000;

    // 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;

    // 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.
    nCellsBetweenLevels 2;



    // 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        "innerCylinderSmall.eMesh";
            level       2;
        }
        {
            file        "outerCylinder.eMesh";
            level       0;
        }
        {
            file        "propellerTip.eMesh";
            level       0;
        }
        {
            file        "propellerSpinner.eMesh";
            level       0;
        }
    );



    // 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
    {
        innerCylinderSmall
        {
            level       (2 2);

            faceType    boundary;
            cellZone    innerCylinderSmall;
            faceZone    innerCylinderSmall;
            cellZoneInside  inside;
        }
        outerCylinder
        {
            level       (0 0);
        }
        propellerTip
        {
            level       (1 10);
        }
        propellerSpinner
        {
            level       (1 6);
        }  
    }

    // Resolve sharp angles
    resolveFeatureAngle 2.5;


    // Region-wise refinement
    // ~~~~~~~~~~~~~~~~~~~~~~

    refinementRegions
    {
        //innerCylinder
        //{
        //    mode        inside;
        //    levels      ((1E15 5));
        //}
        innerCylinderSmall
        {
            mode        inside;
            levels      ((1E15 2));
        }
        //outerCylinder
        //{
        //    mode        inside;
        //    levels      ((1E15 1));
        //}
    }


    // Mesh selection
    // ~~~~~~~~~~~~~~

    locationInMesh (0.01 -1.5 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;
}



// Settings for the snapping.
snapControls
{
    //- Number of patch smoothing iterations before finding correspondence
    //  to surface
    nSmoothPatch 3;

    //- Relative distance for points to be attracted by surface feature point
    //  or edge. True distance is this factor times local
    //  maximum edge length.
    tolerance 2.0; // 1.0;

    //- Number of mesh displacement relaxation iterations.
    nSolveIter 100;

    //- Maximum number of snapping relaxation iterations. Should stop
    //  before upon reaching a correct mesh.
    nRelaxIter 5;

    // Feature snapping

        // Number of feature edge snapping iterations.
        // Leave out altogether to disable.
        nFeatureSnapIter 10;

        // Detect (geometric only) features by sampling the surface
        // (default=false).
        implicitFeatureSnap false;

        // Use castellatedMeshControls::features (default = true)
        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
    {
        propellerTip
            {
                nSurfaceLayers 3;
            }
        //propellerSpinner
        //    {
        //        nSurfaceLayers 3;
        //    }
    }

    // Expansion factor for layer mesh
    expansionRatio 1.1;

    // 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.
    // Relative to undistorted size of cell outside layer.
    minThickness 0.1;

    // 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.
    // Note: changed(corrected) w.r.t 1.7.x! (didn't do anything in 1.7.x)
    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 3;

    // 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
    // Note: changed(corrected) w.r.t 1.7.x! 90 degrees corresponds to 130
    // in 1.7.x.
    minMedialAxisAngle 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 100;
}



// 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 4;
    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 -1e30; // 1e-30;

    //- 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.01;

    //- Minimum normalised cell determinant
    //  1 = hex, <= 0 = folded or flattened illegal cell
    minDeterminant 0.001;

    //- minFaceWeight (0 -> 0.5)
    minFaceWeight 0.05;

    //- minVolRatio (0 -> 1)
    minVolRatio 0.01;

    //must be >0 for Fluent compatibility
    minTriangleTwist -1;


    // Advanced

    //- Number of error distribution iterations
    nSmoothScale 4;
    //- Amount to scale back displacement at error points
    errorReduction 0.75;

    // 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;
    }
}



// Merge tolerance. Is fraction of overall bounding box of initial mesh.
// Note: the write tolerance needs to be higher than this.
mergeTolerance 1e-6;


// ************************************************************************* //
Although these changes dramatically improved the mesh, especially the block Mesh mods, there are regions, mainly at the blade tip, that still need to get better refined. If I increase the surface refinement level above 10 or 11, I still get the "faces with face pyramid volume < 1e-13" issue mentioned before and the mesh becomes course near the feature edges.

Another issue is that SHM continues to fail to add boundary layers properly on the whole airfoil surface, specially on the leading-edge.

I think that I'll go for a 180 degrees mesh to reduce cell number and improve refinement. I'm getting heavy meshes with these configs and even my university cluster is taking hours to solve.

cfMesh

I felt like I was having the same old problems, but now with a more refined mesh. So I went after alternatives to SHM and found cfMesh which is an openFOAM module and is fully integrated to the OF environment. This video How to create your first mesh with cfMesh - tutorial by József Nagy helped me a lot with the introduction to cfMesh.

It is a much simpler, more intuitive, increadibly fast, and requires fewer configurations compared to SHM. It really surprised me.

I have started meshing with it and the very first mesh I came out with was better than any mesh I had done before with SHM. Not only the surface refinement was excelent, but it succesfully add layers on the whole propeller/airfoil surface. It also executed the mesh in less than a minute, when compared to 10-30 minutes of SHM. I found cfMesh really great, but I'm having difficulties to integrate the mesh to my structure and to dealing with some AMI patches that I still need to figure out as I discuss in this post: [cfMesh] Error when creating AMI patches propeller

Mine cfMesh configs are below. I'm using cartesianMesh, which is composed by hex cells similar to SHM.
meshDict
Code:
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    location    "mesh";
    object      meshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

surfaceFile "combined.fms";

minCellSize 0.005;

maxCellSize 0.01;

boundaryCellSize 0.05;

localRefinement
{
    "propellerTip"
    {
        //cellSize  0.000125;
        additionalRefinementLevels 6;
    }
}

surfaceMeshRefinement
{
    innerCyl
    {
        surfaceFile "innerCylinderSmall.stl";
        
        additionalRefinementLevels 1;     
        
    }
}

boundaryLayers 
{
    //nLayers 3;
    
    thicknessRatio 1.1;
    
    maxFirstLayerThickness 0.5;
    
    patchBoundaryLayers
    {
        "propellerTip"
        {
            nLayers 3;
            
            allowDiscontinuity 0;
        }
    }
}

Attached are some images comparing the meshes
Attached Images
File Type: jpg Imagem1.jpg (19.9 KB, 179 views)
File Type: jpg Imagem2.jpg (137.6 KB, 215 views)
Yann, lourencosm, hogsonik and 1 others like this.

Last edited by gabrielfelix; October 24, 2021 at 12:36.
gabrielfelix is offline   Reply With Quote

Old   July 5, 2023, 21:57
Default
  #7
Member
 
Gabriel Felix
Join Date: May 2021
Location: Brazil
Posts: 35
Rep Power: 6
gabrielfelix is on a distinguished road
Hello guys, I finally found a solution to the problem and managed to mesh the propeller case with cfMesh succesfully. I posted the detailed solution in this thread.
[Guide] How to mesh a propeller domain using cfMesh - AMI patch
Case files are also available.
Yann likes this.
gabrielfelix is offline   Reply With Quote

Reply

Tags
leading edge, mesh, rough, snap, trailing edge


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Help with UDF for Hinged Leading and Trailing Edge Deflections tsprengeler FLUENT 0 August 12, 2021 15:59
Meshing near leading and trailing edge of propeller surajp92 STAR-CCM+ 1 June 1, 2017 02:40
Leading edge and trailing edge of an airfoil rotor blade Jun_Milan CFX 0 July 11, 2014 00:07
Y-Plus values at aerofoil leading edge and trailing edge at high incidence Engr07 Main CFD Forum 4 June 29, 2012 11:42
[DesignModeler] Creating a blunt trailing edge from collapsed leading edge gmd ANSYS Meshing & Geometry 0 March 2, 2012 10:48


All times are GMT -4. The time now is 14:43.