CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Community Contributions

[cfMesh] [Guide] How to mesh a propeller domain using cfMesh - AMI patch

Register Blogs Community New Posts Updated Threads Search

Like Tree7Likes
  • 7 Post By gabrielfelix

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   July 5, 2023, 21:50
Default [Guide] How to mesh a propeller domain using cfMesh - AMI patch
  #1
Member
 
Gabriel Felix
Join Date: May 2021
Location: Brazil
Posts: 35
Rep Power: 6
gabrielfelix is on a distinguished road
[Guide] How to mesh a propeller domain using cfMesh - AMI patch

Hi folks,

I have been struggling to succesfully mesh a propeller domain with good volumetric and surface mesh quality. I initially started using snappyHexMesh, however it has several limitations when you go for high refining levels. I tried then using cfMesh, but I took a long time to use it correctly. Now I'm going to share the procedure I used.

I used this setup for simulating a propeller that I was researching in my master's. With cfMesh I finally managed to have more control over the mesh and obtain more quality.

This document below was the only one that was able to help me thorugh cfMesh. Without it I would not be able to use cfMesh on propellers.
- Modelling of chemical batch reactor


In my master's dissertation I wrote all the details of how I meshed and simulated the propeller. It is available in this link. There are two files in the docs folder:
- Appendix with the details of simulation and meshing (which will be more helpful for you) - SetupOpenFOAM.pdf
- Complete dissertation - FELIX, G. R. Experimental and Computational Investigation of Simulated Horn Ice Shapes on Small-Scale Propeller Performance Degradation. MSc Dissertation - ITA, 2022.pdf

All the mesh elements, names, patches were based on the OpenFOAM propeller tutorial in order to make things easier for who is starting with propeller simulations.

1. Geometry
The mesh domain consists in two regions: a rotating region, called rotor, which is a small cylinder that contains the propeller geometry; and a static cylinder, called stator, which enclosures the rotor region and represents the domain of the propeller flow, as shown in the figure below. The Arbitrary Mesh Interface (AMI) was used to couple the rotor and stator patches which share the same boundaries at their interface.



Important: the stator must be hollow in the rotor region. You can do this by subtracting the inner cylinder from the outer cylinder in the CAD software. I suggest using SALOME or freeCAD. The SetupOpenFOAM.pdf shows the steps to generate the solids with SALOME.

All the files mentioned below are available in Google Drive and github
In the propeller_cfMesh.rar file

1.1 Stator
I use two solids for meshing the stator mesh:
- outerCylinder.stl (external domain for volumetric mesh)
- innerCylinderSmall_slave.stl (internal cylinder in which the rotor region will be located)

mesh with:
# combine files
Code:
cat innerCylinderSmall_slave.stl outerCylinder.stl > combined.stl
# extract edges
Code:
surfaceFeatureEdges combined.stl combined.fms -angle 5
[/CODE]

# mesh
Code:
cartesianMesh
checkMesh
meshDict - stator
Code:
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    location    "mesh";
    object      meshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

surfaceFile "combined.fms";

//minCellSize 0.005;

maxCellSize 0.1;

//boundaryCellSize 0.005;

// Refine region 
surfaceMeshRefinement
{
    domain
    {
        surfaceFile outerCylinder.stl;
        additionalRefinementLevels 3;
        refinementThickness 50;
    }
}

localRefinement
{
    "inneCylinderSmall_slave"
    {
        //cellSize  0.000125;
        additionalRefinementLevels 3;
        refinementThickness 50;
    }
}
Or just run Allrun.pre that is located in the stator folder

1.2 Rotor
I use two solids for meshing the stator mesh:
- innerCylinder.stl (is the same solid of innerCylinderSmall_slave)

mesh with:
# combine files
Code:
cat propellerTip.stl innerCylinderSmall.stl > combined.stl
# extract edges
Code:
surfaceFeatureEdges combined.stl combined.fms -angle 5
[/CODE]

# mesh
Code:
cartesianMesh
checkMesh
meshDict - rotor
Code:
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    location    "mesh";
    object      meshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

surfaceFile "combined.fms";

// minCellSize 0.0025;

maxCellSize 0.01;

//boundaryCellSize 0.05;

// Refine region 
surfaceMeshRefinement
{
    domain
    {
        surfaceFile innerCylinderSmall.stl;
        additionalRefinementLevels 1;
        refinementThickness 10;
    }
}

objectRefinements
{
    box
    {
        type        box;
        additionalRefinementLevels 2;  
        centre      (0.0 0.0 0.0);
        lengthX     0.05;
        lengthY     0.025;
        lengthZ     0.35;
        
    }
}

// Refine the patches within the mesh
localRefinement
{
    propellerTip
    {
        additionalRefinementLevels 4;
        // cellSize    0.001;
    }
}


// // Add inflation layers to the patches
// boundaryLayers 
// {
//     //nLayers 3;
    
//     thicknessRatio 1.1;
//     allowDiscontinuity 1;
    
//     maxFirstLayerThickness 0.5;
     
//     patchBoundaryLayers
//     {
//         propellerTip
//         {
//             nLayers 5;
//         }
//     }
    
//     optimiseLayer 1;  

//     optimisationParameters
//     {
//         nSmoothNormals 5;
//         maxNumIterations 5;
//         featureSizeFactor 0.3;
//         reCalculateNormals 1;
//         relThicknessTol 0.1;
        
//         /*nSmoothNormals 15;
// 		maxNumIterations 15;
// 		featureSizeFactor 0.1;
// 		relThicknessTol 0.001;*

meshQualitySettings
{
    //- Maximum non-orthogonality allowed. Set to 180 to disable.
    maxNonOrtho 65;

    //- Max skewness allowed. Set to <0 to disable.
    maxSkewness 2;
}
I commented out the inflation/boundary layer meshing to simplify the mesh. But you can generate it if you want.

Or just run Allrun.pre that is located in the rotor folder

1.3 Merge stator and rotor meshes

In the "combined" folder I use the following commands to merge the meshes
Code:
cp -r stator/constant/polyMesh constant/
mergeMeshes . rotor -overwrite
topoSet -dict system/createInletOutletSets.topoSetDict
createPatch -overwrite
checkMesh
topoSet -dict system/createAMIFaces.topoSetDict
createInletOutletSets.topoSetDict
Code:
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    object      topoSetDict;
}

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

actions
(
    {
        name    boundaryFaces;
        type    faceSet;
        action  new;
        source  patchToFace;
        patch   outerCylinder;
    }

    {
        name    outletFaces;
        type    faceSet;
        action  new;
        source  faceToFace;
        set     boundaryFaces;
    }
    {
        name    inletFaces;
        type    faceSet;
        action  new;
        source  faceToFace;
        set     boundaryFaces;
    }
    {
        name    outletFaces;
        type    faceSet;
        action  subset;
        source  normalToFace;
        normal  (0 -1 0);
        cos     0.3;    // Tolerance (max cos of angle)
    }
    {
        name    inletFaces;
        type    faceSet;
        action  subset;
        source  normalToFace;
        normal  (0 1 0);
        cos     0.3;    // Tolerance (max cos of angle)
    }
);
createPatchDict
Code:
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    object      createPatchDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

// Do a synchronisation of coupled points after creation of any patches.
// Note: this does not work with points that are on multiple coupled patches
//       with transformations (i.e. cyclics).
pointSync false;

// Patches to create.
patches
(    
    {
        //- Master side patch
        name            AMI1;
        patchInfo
        {
            type            cyclicAMI;
            matchTolerance  0.0001;
            neighbourPatch  AMI2;
            transform       noOrdering;
        }
        constructFrom patches;
        patches (innerCylinderSmall);
    }

    {
        //- Slave side patch
        name            AMI2;
        patchInfo
        {
            type            cyclicAMI;
            matchTolerance  0.0001;
            neighbourPatch  AMI1;
            transform       noOrdering;
        }
        constructFrom patches;
        patches (innerCylinderSmall_slave);
    }


    {
        name inlet;
        patchInfo
        {
            type            patch;
        }
        constructFrom set;
        set inletFaces;
    }
    {
        name outlet;
        patchInfo
        {
            type            patch;
        }
        constructFrom set;
        set outletFaces;
    }
);
createAMIFaces.topoSetdict
Code:
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    object      topoSetDict;
}

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

actions
(
    {
        name    rotor;
        type    cellZoneSet;
        action  new;
        source  setToCellZone;
        sourceInfo
        {
            set     region1;
        }
    }
);
It is important to run checkMesh after creating the patches.

Or just run Allrun.pre that is located in the combined folder

Now the mesh is finished. You will now be able to run the simulation

checkMesh output:
Code:
Checking patch topology for multiply connected surfaces...
                   Patch    Faces   Points                  Surface topology
           outerCylinder    11776    11960  ok (non-closed singly connected)
            propellerTip    76004    75386      ok (closed singly connected)
                    AMI1    19840    19698      ok (closed singly connected)
                    AMI2     3608     3538      ok (closed singly connected)
                   inlet     1918     1973  ok (non-closed singly connected)
                  outlet     1918     1973  ok (non-closed singly connected)

Checking faceZone topology for multiply connected surfaces...
    No faceZones found.

Checking basic cellZone addressing...
                CellZone        Cells       Points       VolumeBoundingBox
                  rotor       414383       497558     0.018764 (-0.2 -0.075 -0.199799) (0.2 0.075 0.199799)
All the patches and rotor cellZone were created succesfully.

2.0 Simulation

You can now use the run folder to run the simulation

# Copy the mesh from combine folder to run folder
Code:
cp -r ../mesh/combine/constant .
# Run simulation
Code:
rhoSimpleFoam
or just execute Allrun script

Important
Download the files to understand more deeply the process. More details are available in the SetupOpenFOAM.pdf and Modelling of chemical batch reactor files

Last edited by gabrielfelix; July 12, 2023 at 10:01.
gabrielfelix is offline   Reply With Quote

Old   October 18, 2023, 17:58
Default
  #2
Member
 
Morteza
Join Date: Jan 2018
Posts: 30
Rep Power: 8
mortezahdr is on a distinguished road
Hello and thank you for sharing your experience.
I have a question regarding interpolation at the interface between the static and rotating blocks of the mesh. It is known that for an acceptable interpolation, the two patches at the interface should be similar in terms of grid topology (number, shape and location of cells). Otherwise, the AMI-weights reported by openfoam during running the sliding mesh case will differ significantly from 1, which eventually leads to divergence.
Now, in your case, the inneCylinderSmall_slave and inneCylinderSmall patches have been created from two different meshDict files, with different cell sizes. The question is, does it result in similar grid distribution/count? Furthermore, in OpenFoam_Report.pdf that you have given a link for, these two patches do not have even close number of cells (cylinders with nFaces = 1376 in page 11, versus CYLINDER with nFaces = 18856 in page 12). Shouldn't this lead to convergence problems for AMI interpolation?
mortezahdr is offline   Reply With Quote

Old   April 2, 2024, 21:28
Default
  #3
Member
 
Gabriel Felix
Join Date: May 2021
Location: Brazil
Posts: 35
Rep Power: 6
gabrielfelix is on a distinguished road
Quote:
Originally Posted by mortezahdr View Post
Hello and thank you for sharing your experience.
I have a question regarding interpolation at the interface between the static and rotating blocks of the mesh. It is known that for an acceptable interpolation, the two patches at the interface should be similar in terms of grid topology (number, shape and location of cells). Otherwise, the AMI-weights reported by openfoam during running the sliding mesh case will differ significantly from 1, which eventually leads to divergence.
Now, in your case, the inneCylinderSmall_slave and inneCylinderSmall patches have been created from two different meshDict files, with different cell sizes. The question is, does it result in similar grid distribution/count? Furthermore, in OpenFoam_Report.pdf that you have given a link for, these two patches do not have even close number of cells (cylinders with nFaces = 1376 in page 11, versus CYLINDER with nFaces = 18856 in page 12). Shouldn't this lead to convergence problems for AMI interpolation?
Yes, I think you are absolutely right. You can set the refinement level of these patches to be similar to each other and apply some refinement zones inside innerCylinderSmall with other strategies such a cylinder refinement zone contained inside innerCylinderSmall. This way innerCylinderSmall and _slave can have the same refinement levels.
gabrielfelix is offline   Reply With Quote

Reply

Tags
ami, cfmesh, mesh, openfoam, propeller


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
[Other] Wedge patch '*' is not planar LilumDaru OpenFOAM Meshing & Mesh Conversion 7 September 18, 2024 06:52
Problem using AMI vinz OpenFOAM Running, Solving & CFD 298 November 13, 2023 09:19
Out File does not show Imbalance in % Mmaragann CFX 5 January 20, 2017 11:20
Sudden increase the residual of Maxwell's equations hsezsz CFX 2 October 13, 2016 07:58
[OpenFOAM.org] Compile OF 2.3 on Mac OS X .... the patch gschaider OpenFOAM Installation 225 August 25, 2015 20:43


All times are GMT -4. The time now is 12:45.