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

[snappyHexMesh] SHM not snapping to some surfaces

Register Blogs Community New Posts Updated Threads Search

Like Tree8Likes
  • 1 Post By Swift
  • 2 Post By wyldckat
  • 4 Post By Swift
  • 1 Post By Swift

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   November 7, 2015, 04:54
Default SHM not snapping to some surfaces
  #1
Member
 
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11
Swift is on a distinguished road
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:
  • increase and decrease the tolerance from as low as 0.25 up to 10.0
  • change the resolveFeatureAngle
  • increase the feature and surface refinementd levels
  • increasing the snapControl number of iterations for every parameter I can
  • resaved the rotor geometry (the impeller) to a higher resolution as stl. Currently the file is about 3 MB. I don't know how much difference this makes. I also reduced the aspect ratios of of the triangles to increase the stl quality.
  • changed the minTetQuality from 1e-15 to -1E30 and back
  • played with the includedAngle changing it from 150 to 180 degrees.
I feel like I am stabbing in the dark here and don't know really what I should be focussing on to try and get my mesh working.


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;


// ************************************************************************* //
here is my SHMdict default file


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;
Could someone please help me resolve this?



Regards,

Thomas

Last edited by wyldckat; November 7, 2015 at 10:18. Reason: removed broken image links
Swift is offline   Reply With Quote

Old   November 7, 2015, 12:39
Default
  #2
Retired Super Moderator
 
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,982
Blog Entries: 45
Rep Power: 128
wyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to all
Quick answer:
  1. Without a test case, it's very hard to diagnose the problem. If you can either share your case or create a small part of your geometry that has the problem and try to mesh it, you can then share it.
    • If you share only a small enough part of your geometry in the shared case, which can reproduce this error, then that will make it a lot easier to help you and it's nearly impossible to reverse engineer the whole geometry you are using.
  2. After a quick glance, my only suspect is the maximum cell count:
    Code:
        maxLocalCells 100000;
    
        maxGlobalCells 2000000;
wyldckat is offline   Reply With Quote

Old   November 7, 2015, 16:07
Default
  #3
Member
 
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11
Swift is on a distinguished road
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
wyldckat likes this.
Swift is offline   Reply With Quote

Old   November 8, 2015, 06:01
Default
  #4
Member
 
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11
Swift is on a distinguished road
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
Swift is offline   Reply With Quote

Old   November 8, 2015, 07:01
Default
  #5
Retired Super Moderator
 
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,982
Blog Entries: 45
Rep Power: 128
wyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to all
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:
Now, for the problem on the rotor, the diagnosis strategy is simple:
  1. Renamed the folder "0" to "0.org", because we are still creating the mesh and the boundary conditions will only get in the way.
  2. Created an empty folder "0". This is needed for mesh visualization.
  3. Clean up the case and run the meshing steps. But don't use the "-overwrite" option with snappyHexMesh.
  4. The result is shown in the attached images:
    1. "Geometry.png" - shows the rotor geometry
    2. "castellation 2.png" - shows the castellated step, which is the first time step (not the 0 one). Notice anything strange already?
    3. "Geometry wireframe with snapped.png" - shows the final mesh surface of the rotor (the 2nd time step), along with the wire-frame of the original STL file.
I don't know if you noticed it already, but you're asking a lot from snappyHexMesh. The major problems I can spot right away with just visual inspection are:
  1. As shown in "castellation 2.png", there are parts of the mesh that have no thickness available for representing the STL surface. There is an option introduced in OpenFOAM 2.3.0 that has something that might help: http://www.openfoam.org/version2.3.0/snappyHexMesh.php - namely "detectNearSurfacesSnap" and "gapLevelIncrement".
  2. But without enough cell thickness, snappyHexMesh doesn't know should be done with the cells around this geometry, since it's ambiguous to which side they should be snapped to.
  3. snappyHexMesh usually needs at least 2 cells of thickness in order to represent the mesh properly.
  4. If the rotor has enough refinement defined in "snappyHexMeshDict", then the problem could be due to the base mesh being two coarse, making it rather complicated for snappyHexMesh to see the surfaces in the rotor STL file, because the base mesh and subsequent refinements are used for seeing the surfaces. If one of the refinements doesn't provide enough refinement for seeing the STL, then it simply is not seen by snappyHexMesh.


Best regards,
Bruno
Attached Images
File Type: png Geometry.png (41.7 KB, 754 views)
File Type: png castellation 2.png (74.1 KB, 724 views)
File Type: png Geometry wireframe with snapped.png (174.3 KB, 688 views)
wyldckat is offline   Reply With Quote

Old   November 9, 2015, 07:12
Default
  #6
Member
 
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11
Swift is on a distinguished road
Hi Bruno,


Quote:
First, two important references:http://openfoamwiki.net/index.php/SnappyHexMesh - take the time to read the information available here and that is linked to.
http://openfoamwiki.net/index.php/FA...is_in_ParaView - mesh visual inspection is very important... I wasn't sure if you were already following the instructions written there.
Thank you for these links. I have started reading them and no, I was not using those instructions.

Quote:

Now, for the problem on the rotor, the diagnosis strategy is simple:
  1. Renamed the folder "0" to "0.org", because we are still creating the mesh and the boundary conditions will only get in the way.
  2. Created an empty folder "0". This is needed for mesh visualization.
  3. Clean up the case and run the meshing steps. But don't use the "-overwrite" option with snappyHexMesh.
  4. The result is shown in the attached images:
    1. "Geometry.png" - shows the rotor geometry
    2. "castellation 2.png" - shows the castellated step, which is the first time step (not the 0 one). Notice anything strange already?
    3. "Geometry wireframe with snapped.png" - shows the final mesh surface of the rotor (the 2nd time step), along with the wire-frame of the original STL file.

(1-3) - I was just using overwrite, but this is very useful. I'm learning something already.
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:
I don't know if you noticed it already, but you're asking a lot from snappyHexMesh. The major problems I can spot right away with just visual inspection are:
  1. As shown in "castellation 2.png", there are parts of the mesh that have no thickness available for representing the STL surface. There is an option introduced in OpenFOAM 2.3.0 that has something that might help: http://www.openfoam.org/version2.3.0/snappyHexMesh.php - namely "detectNearSurfacesSnap" and "gapLevelIncrement".
  2. But without enough cell thickness, snappyHexMesh doesn't know should be done with the cells around this geometry, since it's ambiguous to which side they should be snapped to.
  3. snappyHexMesh usually needs at least 2 cells of thickness in order to represent the mesh properly.
  4. If the rotor has enough refinement defined in "snappyHexMeshDict", then the problem could be due to the base mesh being two coarse, making it rather complicated for snappyHexMesh to see the surfaces in the rotor STL file, because the base mesh and subsequent refinements are used for seeing the surfaces. If one of the refinements doesn't provide enough refinement for seeing the STL, then it simply is not seen by snappyHexMesh.

1 - "detectNearSurfacesSnap" and "gapLevelIncrement". I tried to find more information about using these features but was unable to find an example. As I understand "detectNearSurfacesSnap", it is designed to resolve my sort of problem so I don't think I should be disabling it. Am I correct? I have also tried to find information of "gapLevelIncrement". My understanding is that I need to define the level for each geometry stl file in the ::refinementSurfaces subdict for the snappHexMeshDict file. For example:

Code:
Rotorb
        {
            // Surface-wise min and max refinement level
            level (7 7);
//- Optional increment (on top of max level) in small gaps
    gapLevelIncrement 1;

        }
I am basing this on http://www.cfd-online.com/Forums/ope...jects-gap.html. I will still have to experiment with this to see if it helps. I can foresee it being useful in the final model later.

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
Attached Images
File Type: png geometry.png (35.0 KB, 352 views)
File Type: png Geometry-Castellated.png (27.2 KB, 396 views)
File Type: png geometry-Improved.png (38.4 KB, 366 views)
File Type: png Geometry-snapStep.png (37.1 KB, 451 views)
Swift is offline   Reply With Quote

Old   November 9, 2015, 07:53
Default
  #7
Member
 
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11
Swift is on a distinguished road
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
Swift is offline   Reply With Quote

Old   November 10, 2015, 09:34
Default
  #8
Member
 
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11
Swift is on a distinguished road
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:
  1. I meshed only the rotor by moving the locationInMesh entry inside the rotor, and
  2. removing all other geometry and only meshing the rotor but by leaving the locationInMesh outside the rotor. I removed the tank and the AMI surfaces. This means when I meshed the rotor I was only left with the rotor 'cut out' of the original blockMesh mesh.
In both cases the rotor was correctly meshed.


This proved a few things to me:
  1. There is nothing wrong with my stl files. This is also true for lower resolution files,
  2. SHM can see the surfaces and there is therefore some other reason why it is not meshing these surfaces, although I don't know what,
  3. My refinement levels of features and surfaces are adequate, and
  4. The error arises due to the other geometry, in particular the tank because when I meshed with the AMI surface included the rotor was also meshed.
To try eliminate this problem with the tank, I replaced the tank stl entry in the snappyHexMeshDict with a refinementCylinder but this did not resolve the problem.


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
Swift is offline   Reply With Quote

Old   November 15, 2015, 15:38
Default
  #9
Retired Super Moderator
 
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,982
Blog Entries: 45
Rep Power: 128
wyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to all
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.
  • Still confused? Imagine that each point (vertex) in the castellated mesh has a sphere centred on it and has the radius of "tolerance times largest edge connected to this point".

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
//);
The "mesh" flag is the most relevant one, since it shows how the mesh gradually is changed. Make sure you don't use the "-overwrite" argument when running snappyHexMesh. Each time step will then show you a snapshot of the mesh after an iteration of mesh manipulation.

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
wyldckat is offline   Reply With Quote

Old   November 20, 2015, 03:44
Default
  #10
Member
 
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11
Swift is on a distinguished road
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:
  1. I placed the location of the mesh within the rotor and it meshed without any problems. Snapping worked perfectly.
  2. If I excluded the tank, and meshed within the AMI volume (the rotating part of the mesh), both the AMI surface and the rotor surface meshed perfectly!
  3. Meshing the tank and the AMI surface, i.e the tank volume excluding the AMI volume or stated otherwise, the stationary part of the mesh, resulted in a good mesh.
  4. The problem was that as soon as I tried to mesh them all together, it created this blocky mesh that we have been discussing. I even thickened the rotor blade thickness from 4 mm to 20 mm to make remove the ambiguity for sHM when two surfaces are too close together. Unfortunately, I have not been able to find a good explanation as to why a poor mesh results or what settings I should change. I also swapped the tank and AMI stl files and used searchableCylinders instead, trying to eliminate potential problems with the geometry
  5. I think that all the above steps showed that there is nothing wrong with the geometry files.
  6. While doing these steps, I made a point of not changing mesh settings in sHM nor changing the blockMesh file. All I changed was the locationInMesh point to mesh the different parts. I thought that by doing this I would be able to prove that there is nothing wrong with my sHM set up.
  7. I then meshed the stationary and rotating parts separately and merged the meshes using mergeMeshes. I did not use stitchMesh according to your post http://www.cfd-online.com/Forums/ope...tml#post446517 and ran the model and it worked!!
I have subsequently, run a few models this way. While I would prefer to be able to mesh in one step and avoid using mergeMeshes as it requires a few more manual steps, I need to get a model running and this way seems to be working. I will continue to post here if I find out what is going wrong. I suspect that it is something that I'm doing, because I don't think it is such a complicated geometry that sHM can't handle it.


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 15:51. Reason: fixed broken link
Swift is offline   Reply With Quote

Old   November 29, 2015, 11:50
Default
  #11
Retired Super Moderator
 
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,982
Blog Entries: 45
Rep Power: 128
wyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to all
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
wyldckat is offline   Reply With Quote

Old   November 30, 2015, 05:27
Default
  #12
Member
 
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11
Swift is on a distinguished road
Hi Bruno,

Quote:
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...
It is very strange that it doesn't work especially considering that I have based what I have done on the propeller example. I don't know if you noticed, but my AMI fazeZone is very close to the edge of the rotors. To explain this a little clearer, my rotor diameter is 800 mm and the AMI cylinder diameter is 880 mm. I did this to reduce the number of cells in the rotating domain. I suspect that moving the cells to be a computationally expensive operation and if can I reduce the number of cells I can improve the solution time. Is it however possible that sHM is getting confused because it is trying to mesh the faceZone while still trying to snap to geometry that is too close to this faceZone?

Quote:
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?
Yes, I use the same blockMeshDict file. While I realise that this is probably inefficient when meshing, I do this to ensure that the AMI surfaces (the faceZones you referred to) are as similar as possible when meshing the tank and when meshing the rotor volumes. I'm no sHM expert, but I think that this should result in similar (hopefully the same) number of faces on the AMI surface for the rotor (Master AMI surface) mesh and the tank mesh (Slave AMI mesh). Additionally, it ensures that the vertices of the meshes for the master and slave AMI surfaces are close to each other. I have found that this works quite well. As an example, the case I am currently solving reports that I have 7752 source and 7696 target faces. The difference in the number of faces between the master AMI and slave AMI faces is therefore approximately 0.7%. I could make a smaller blockMesh that encompasses the rotor more closely while maintaining the same aspect ratios and block positions, but the meshing time is relatively short that I don't think there is a practical advantage to doing this.

Best regards,
Thomas
Swift is offline   Reply With Quote

Old   November 30, 2015, 16:58
Default
  #13
Retired Super Moderator
 
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,982
Blog Entries: 45
Rep Power: 128
wyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to all
Hi Thomas,

Quote:
Originally Posted by Swift View Post
It is very strange that it doesn't work especially considering that I have based what I have done on the propeller example. I don't know if you noticed, but my AMI fazeZone is very close to the edge of the rotors. To explain this a little clearer, my rotor diameter is 800 mm and the AMI cylinder diameter is 880 mm. I did this to reduce the number of cells in the rotating domain. I suspect that moving the cells to be a computationally expensive operation and if can I reduce the number of cells I can improve the solution time. Is it however possible that sHM is getting confused because it is trying to mesh the faceZone while still trying to snap to geometry that is too close to this faceZone?
This reminds me of something... Have you tried the option explained here: http://www.openfoam.org/version2.2.0...h.php#x4-12000 - section "Baffle and Boundary Creation". Because the "baffle" or "boundary" types might make it easier for snappyHexMesh to decide which meshing strategy to use.

Quote:
Originally Posted by Swift View Post
Yes, I use the same blockMeshDict file. While I realise that this is probably inefficient when meshing, I do this to ensure that the AMI surfaces (the faceZones you referred to) are as similar as possible when meshing the tank and when meshing the rotor volumes. I'm no sHM expert, but I think that this should result in similar (hopefully the same) number of faces on the AMI surface for the rotor (Master AMI surface) mesh and the tank mesh (Slave AMI mesh). Additionally, it ensures that the vertices of the meshes for the master and slave AMI surfaces are close to each other. I have found that this works quite well. As an example, the case I am currently solving reports that I have 7752 source and 7696 target faces. The difference in the number of faces between the master AMI and slave AMI faces is therefore approximately 0.7%. I could make a smaller blockMesh that encompasses the rotor more closely while maintaining the same aspect ratios and block positions, but the meshing time is relatively short that I don't think there is a practical advantage to doing this.
OK, this is a good practice, namely to use the same base mesh.

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
wyldckat is offline   Reply With Quote

Old   January 4, 2016, 02:56
Default
  #14
Member
 
Thomas Sprich
Join Date: Mar 2015
Posts: 76
Rep Power: 11
Swift is on a distinguished road
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:
This reminds me of something... Have you tried the option explained here: http://www.openfoam.org/version2.2.0...h.php#x4-12000 - section "Baffle and Boundary Creation". Because the "baffle" or "boundary" types might make it easier for snappyHexMesh to decide which meshing strategy to use.
With regards to your suggestion, I have tried using both the baffle and boundary conditions. Originally I was using the baffle condition as this seems to me to be the correct one to use. I found that in if I used the boundary condition, the rotor would mesh properly, but the AMI plane would not be co-planar for the master and slave patches. The problem is therefore moving from not meshing the rotor properly to not meshing the AMI plane properly.

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
wyldckat likes this.
Swift is offline   Reply With Quote

Reply


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
[snappyHexMesh] SHM not snapping on simple case slaners OpenFOAM Meshing & Mesh Conversion 7 June 6, 2018 07:43
[snappyHexMesh] SHM doesn't create cellZones for one region Eko OpenFOAM Meshing & Mesh Conversion 10 January 24, 2018 03:03
[snappyHexMesh] SHM Problems with snapping and layers Rojj OpenFOAM Meshing & Mesh Conversion 0 April 14, 2016 14:52
[snappyHexMesh] Can't couple front & back faces in cyclic BC after snapping in SHM hakonbar OpenFOAM Meshing & Mesh Conversion 4 December 8, 2013 17:50
[snappyHexMesh] SHM: feature edge snapping not conforming thab OpenFOAM Meshing & Mesh Conversion 3 November 26, 2012 15:04


All times are GMT -4. The time now is 08:06.