CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Community Contributions (https://www.cfd-online.com/Forums/openfoam-community-contributions/)
-   -   [Other] [cfMesh] Error when creating AMI patches propeller (https://www.cfd-online.com/Forums/openfoam-community-contributions/239127-cfmesh-error-when-creating-ami-patches-propeller.html)

gabrielfelix October 21, 2021 14:23

[cfMesh] Error when creating AMI patches propeller
 
2 Attachment(s)
Hi folks,

I've been running propeller simulations over the last months, and I had been using snappyHexMesh for meshing the propeller geometry and simulation domain before jumping into cfMesh. My simulation structure is completely based on the pimpleFoam propeller tutorial, except that I modified it to run my geometry in compressible steady-state (rhoSimpleFoam) and using MRF technique.

SHM meshes were never as refined as they should be, specially at the leading-edge and near the blade tips. As reported in this thread:
[snappyHexMesh] Rough leading-edge and trailing-edge after snapping, I spent around 2 months trying to improve the mesh, which I actually did, however not sufficiently as I wanted. SHM fails to refine the surface after a certain surface refinement level and also fails to add boundary layers properly to the surface.

After researching for alternatives I came across cfMesh through this video: How to create your first mesh with cfMesh - tutorial by József Nagy that helped me a lot with the introduction to the mesher. 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 added 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 simulation structure and to dealing with some AMI patches, which I'm going to further detail next.

My domain is composed by:
- propellerTip: are the prop blades
- propellerSpinner: the prop spinner
- innerCylinderSmall: the "moving" domain
- outerCylinder: an outer cylinder that contains the other patches as well as the farfield upstream and downstream of the propeller

https://i.imgur.com/Dk7HAJK.png

snappyHexMesh
The meshing process that I was using was: create a blockMesh wrapping the whole domain; extract stl file surface with surfaceFeatureExtract, mesh with snappyHexMesh;configure the boundary, inlet and outlet face sets; and finally create AMI, inlet and outlet patches.

Code:

blockMesh
surfaceFeatureExtract
snappyHexMesh
topoSet -dict system/createInletOutletSets.topoSetDict
createPatch -overwrite

blockMeshDict:
Code:

scale  1;
convertToMeters  1;

vertices
(
    (-0.65 -0.65 -0.65)
    ( 0.65 -0.65 -0.65)
    ( 0.65  0.65 -0.65)
    (-0.65  0.65 -0.65)
    (-0.65 -0.65  0.65)
    ( 0.65 -0.65  0.65)
    ( 0.65  0.65  0.65)
    (-0.65  0.65  0.65)
);


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:

castellatedMesh true;
snap            true;
addLayers      true;

geometry
{
    innerCylinderSmall.stl
        {
                type triSurfaceMesh;
                name innerCylinderSmall;
        }
        outerCylinder.stl
        {
                type triSurfaceMesh;
                name outerCylinder;
        }
        propellerTip.stl
        {
                type triSurfaceMesh;
                name propellerTip;
        }
    propellerSpinner.stl
        {
                type triSurfaceMesh;
                name propellerSpinner;
        }
}


castellatedMeshControls
{

    maxLocalCells 1000000;

    maxGlobalCells 15000000;

    minRefinementCells 0;

    maxLoadUnbalance 0.10;

    nCellsBetweenLevels 2;



    features
    (
        {
            file        "innerCylinderSmall.eMesh";
            level      2;
        }
        {
            file        "outerCylinder.eMesh";
            level      0;
        }
        {
            file        "propellerTip.eMesh";
            level      9;
        }
        {
            file        "propellerSpinner.eMesh";
            level      6;
        }
    );



    refinementSurfaces
    {
        innerCylinderSmall
        {
            level      (2 2);

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

    resolveFeatureAngle 0.1;


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

    locationInMesh (0.01 -0.125 0.01);

    allowFreeStandingZoneFaces false;
}


snapControls
{
    nSmoothPatch 3;

    tolerance 1.0; // 1.0;

    nSolveIter 100;

    nRelaxIter 5;

        nFeatureSnapIter 10;

        implicitFeatureSnap true;

        explicitFeatureSnap false;

        multiRegionFeatureSnap true;
}


addLayersControls
{
    relativeSizes true;

    layers
    {
                "propellerTip.*"
                        {
                                nSurfaceLayers 3;
                        }
    }

    expansionRatio 1.0;

    finalLayerThickness 0.3;

    minThickness 0.1;

    nGrow 0;

    featureAngle 30;

    nRelaxIter 3;

    nSmoothSurfaceNormals 1;

    nSmoothNormals 3;

    nSmoothThickness 10;

    maxFaceThicknessRatio 0.5;

    maxThicknessToMedialRatio 0.3;

    minMedialAxisAngle 90;

    nBufferCellsNoExtrude 0;

    nLayerIter 100;
}


meshQualityControls
{
    maxNonOrtho 65;

    maxBoundarySkewness 4;
    maxInternalSkewness 4;

    maxConcave 80;

    minVol 1e-13;

    minTetQuality -1e30; // 1e-30;

    minArea -1;

    minTwist 0.01;

    minDeterminant 0.001;

    minFaceWeight 0.05;

    minVolRatio 0.01;

    minTriangleTwist -1;


    nSmoothScale 4;

    errorReduction 0.75;

    relaxed
    {
        maxNonOrtho 75;
    }
}

mergeTolerance 1e-6;


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

createInletOutletSets.topoSetDict:
Code:

/*--------------------------------*- C++ -*----------------------------------*\
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:

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

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

cfMesh

Now, for cfMesh I tried to keep as much of the previous workflow as possible, however, as seen in this post: Problem using AMI post #184, due to cfMesh limitations I had to create two separate meshes: rotor containing innerCylinderSmall, propellerTip, and propellerSpinner; and stator containing outerCylinder. An then I merged them together with mergeMesh.

I created the mesh on both rotor and stator folders as
Code:

surfaceFeatureEdges rotor.stl rotor.fms
cartesianMesh

surfaceFeatureEdges stator.stl stator.fms
blockMesh
cartesianMesh

with meshDict.rotor:
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;
    location    "mesh";
    object      meshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

surfaceFile "rotorSlave.fms";

minCellSize 0.005;

maxCellSize 0.01;

boundaryCellSize 0.05;

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

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

meshDict.stator:
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;
    location    "mesh";
    object      meshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

surfaceFile "outerCylinder.fms";

minCellSize 0.01;

maxCellSize 0.1;

boundaryCellSize 0.1;

Then I execute:
Code:

cd stator
mergeMeshes . ../rotor
topoSet -dict system/createInletOutletSets.topoSetDict
createPatch -overwrite

However, createPatch fails to create AMI2 patch because the innerCylinderSmall_slave patch, which is created as simrego described on this thread below:
Quote:

Originally Posted by simrego (Post 718193)
Hi!


If I'm correct it is made in the refinementSurfaces/innerCylinderSmall entry where you define the faceType as boundary. So you split the mesh with walls. Then in the createPatch utility you correct it and create the cyclicAMI interface between them.

is not created under cfMesh enveironment.

I tried many and many things that I saw in multiple threads without any success. I need to create the innerCylinderSmall_slave patch, but I dont know how to copy or duplicate the patch innerCylinderSmall.


What do you folks think I should do? But trying to keep as much of the original workflow?

I'll make available both the snappyHexMesh and cfMesh case folder which I mentioned above:
https://drive.google.com/file/d/1uq8...ew?usp=sharing



createPatch log:
Code:

/*---------------------------------------------------------------------------*\
| =========                |                                                |
| \\      /  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  : createPatch -overwrite
Date  : Oct 21 2021
Time  : 15:01:31
Host  : MSI
PID    : 640
I/O    : uncollated
Case  : /mnt/c/Users/Felix/Documents/Mestrado/OpenFOAM/runs/liuPropeller/3liuAs31mscD30implicit/mesh/stator
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 polyMesh for time = 0

Reading "system/createPatchDict"

Adding new patch AMI1 as patch 4 from
{
    type            cyclicAMI;
    matchTolerance  0.0001;
    neighbourPatch  AMI2;
    transform      noOrdering;
}

Adding new patch AMI2 as patch 5 from
{
    type            cyclicAMI;
    matchTolerance  0.0001;
    neighbourPatch  AMI1;
    transform      noOrdering;
}

Adding new patch inlet as patch 6 from
{
    type            patch;
}

Adding new patch outlet as patch 7 from
{
    type            patch;
}


Moving faces from patch innerCylinderSmall to patch 4
--> FOAM Warning :
    From Foam::labelHashSet Foam::polyBoundaryMesh::patchSet(const Foam::UList<Foam::wordRe>&, bool, bool) const
    in file meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C at line 896
    Cannot find any patch or group names matching innerCylinderSmall_slave
Read 5050 faces from faceSet inletFaces
Read 4964 faces from faceSet outletFaces

Doing topology modification to order faces.

Not synchronising points.

Removing patches with no faces in them.

Removing zero-sized patch innerCylinderSmall type wall at position 1
Removing patches.
Writing repatched mesh to 0

End

boundary file with AMI2 with zero faces:
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      binary;
    class      polyBoundaryMesh;
    arch        "LSB;label=32;scalar=64";
    location    "constant/polyMesh";
    object      boundary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

7
(
    outerCylinder
    {
        type            wall;
        inGroups        1(wall);
        nFaces          18590;
        startFace      16194675;
    }
    propellerSpinner
    {
        type            wall;
        inGroups        1(wall);
        nFaces          14725;
        startFace      16213265;
    }
    propellerTip
    {
        type            wall;
        inGroups        1(wall);
        nFaces          1030388;
        startFace      16227990;
    }
    AMI1
    {
        type            cyclicAMI;
        inGroups        1(cyclicAMI);
        nFaces          9448;
        startFace      17258378;
        matchTolerance  0.0001;
        transform      noOrdering;
        neighbourPatch  AMI2;
        AMIMethod      faceAreaWeightAMI;
        restartUncoveredSourceFace 1;
    }
    AMI2
    {
        type            cyclicAMI;
        inGroups        1(cyclicAMI);
        nFaces          0;
        startFace      17267826;
        matchTolerance  0.0001;
        transform      noOrdering;
        neighbourPatch  AMI1;
        AMIMethod      faceAreaWeightAMI;
        restartUncoveredSourceFace 1;
    }
    inlet
    {
        type            patch;
        nFaces          5050;
        startFace      17267826;
    }
    outlet
    {
        type            patch;
        nFaces          4964;
        startFace      17272876;
    }
)

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

Images from the differences of SHM and cfMesh meshes. Left SHM, right cfMesh

gabrielfelix October 27, 2021 11:38

[update]
 
Hi folks,

I succesfully created the faceSet, cellSet, faceZone and cellZone with the following topoSet script:

Code:

/*--------------------------------*- C++ -*----------------------------------*\
| =========                |                                                |
| \\      /  F ield        | OpenFOAM: The Open Source CFD Toolbox          |
|  \\    /  O peration    | Version:  2.1.x                                |
|  \\  /    A nd          | Web:      www.OpenFOAM.org                      |
|    \\/    M anipulation  |                                                |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version    2.0;
    format      ascii;
    class      dictionary;
    object      topoSetDict;
}

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

actions
(
    // ==================================================
       
    {
        name    innerCylinderSmallCell;
        type    cellSet;
        action  new;
        source  patchToCell;
        sourceInfo
        {
            patch    innerCylinderSmall;
        }
    }
   
    {
        name    innerCylinderSmallFace;
        type    faceSet;
        action  new;
        source  patchToFace;
        sourceInfo
        {
            patch    innerCylinderSmall;
        }
    }
   
    {
        name    innerCylinderSmallFaceZone;
        type    faceZoneSet;
        action  new;
        source  setsToFaceZone;
        sourceInfo
        {
            faceSet    innerCylinderSmallFace;
            cellSet    innerCylinderSmallCell;
        }
    }
   
    {
        name    innerCylinderSmallCellZone;
        type    cellZoneSet;
        action  new;
        source  setToCellZone;
        sourceInfo
        {
            set    innerCylinderSmallCell;
        }
    }
   
);


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

such as they are created under these snappyHexMeshDict lines:
Code:

refinementSurfaces
    {
        innerCylinderSmall
        {
            level      (2 2);

            faceType    boundary;
            cellZone    innerCylinderSmall;
            faceZone    innerCylinderSmall;
            cellZoneInside  inside;
        }

However, now I still need to create the AMI patches, for which I tried to create baffles from the faceZone I just created, but I had no success with this code:
Code:

/*--------------------------------*- C++ -*----------------------------------*\
| =========                |                                                |
| \\      /  F ield        | OpenFOAM: The Open Source CFD Toolbox          |
|  \\    /  O peration    | Version:  2.3.0                                |
|  \\  /    A nd          | Web:      www.OpenFOAM.org                      |
|    \\/    M anipulation  |                                                |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version    2.0;
    format      ascii;
    class      dictionary;
    object      createBafflesDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

internalFacesOnly true;

baffles
{
    innerCylinderSmall
    {
        type                faceZone;
        zoneName        innerCylinderSmallFaceZone;
            flip                false;
       
        patches
        {
            master
            {
                name            innerCylinderSmall;
                type            patch;
                neighbourPatch  innerCylinderSmall_slave;
            }
            //slave { ${..master} }
            slave
            {
                name            innerCylinderSmall_slave;
                type            patch;
                neighbourPatch  innerCylinderSmall;
            }
        }
    }
}

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

Does anyone could help me?

gabrielfelix July 5, 2023 20:54

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.


All times are GMT -4. The time now is 10:37.