一、SnappyHexMesh是什么?

snappyHexMesh,从曲面几何图形、tri-surfaces的.stl或.obj格式文件,生成包含六面体(hex)和分裂六面体(split-hex)的三维几何网格。

二、使用SnappyHexMesh生成网格

链接: https://cfd.direct/openfoam/user-guide/v8-snappyHexMesh/#x27-1970098.

1.snappyHexMesh的网格生成过程

snappyHexMesh的2D网格示意图
目标是网格化一个矩形形状的区域(图中灰色阴影),围绕一个由tri-surface描述的对象。虽然snappyHexMesh是一个3D网格工具,这里举2D的例子是为了易于理解。

在使用snappyHexMesh之前,用户需要符合以下要求:

  1. case路径constant/triSurface包含tri-surface文件
  2. 定义了计算域的范围和基本网格密度的背景hex网格;通常使用blockMesh生成
  3. snappyHexMeshDict字典文件位于system文件夹下面

snappyHexMeshDict字典包括:控制网格划分过程各个阶段的开关,每个过程都有单独的子目录。如下所示:
4. castellatedMesh: 打开castellatedMesh的创建。
5. snap: 切换到表面抓取阶段
6. addLayers: 打开表面层插入。
7. mergeTolerance: :合并公差作为初始网格边界框的部分。
8. geometry:castellatedMeshControls的子字典。
9. snapControls: 用于表面抓取的控件子字典。
10. addLayersControls: 添加图层控件的子字典。
11. meshQualityControls: 控制网格质量的子字典。

创建背景hex网格
在执行snappyHexMesh之前,用户必须创建一个六面体网格的背景网格,它通过外部边界填充整个区域。
生成snappyHexMesh的初始网格
cell在特征边缘和表面的分割
单元格分割是根据用户在snappyHexMeshDict中的castellatedMeshControls子字典中提供的规范执行的。castellatedMeshControls的条目如下所示:
12. locationInMesh:要划分网格的区域内的位置矢量
13. maxLocalCells:细化期间每个处理器的最大单元数。
14. maxGlobalCells:细化期间(即移除之前)的整体单元格限制。
15. minRefinementCells:如果minRefinementCells≥要细化的单元数,表面细化停止。
16. nCellsBetweenLevels:连续的细化级别之间的单元格的缓冲层数(通常设置为3)。
17. resolveFeatureAngle:对能够看到角度超过resolveFeatureAngle(通常设置为30)的交叉的单元格应用最大程度的细化。
18. feature:用于细化的feature列表。
19. refinementSurfaces:用于细化的曲面字典。
20. refinementRegions:用于细化的区域字典。
snappyHexMesh特征边缘的单元分割

features
(
    {
        file "features.eMesh"; // file containing edge mesh
        level 2;               // 网格细化水平
    }
);

包含这些特性的edgeMesh可以使用surfaceFeatures工具从tri-sutface文件中提取

surfaceFeatures

特征网格细化
refinementSurfaces字典位于castellatedMeshControls
level定义了最小和最大的细化水平,格式为( )

refinementSurfaces
{
    sphere1
    {
        level (2 2); // default (min max) refinement for whole surface
        regions
        {
            secondSolid
            {
                level (3 3); // optional refinement for secondSolid region
            }
        }
    }
}

单元格移除
一旦特征和表面分割完成,单元格的移除过程就开始了。单元格被保留的区域仅通过该区域内的位置向量进行标识,该位置向量由castellatedMeshControls中的关键词locationInMesh提供。如果体积的50%或者更多在区域内,单位网格则被保留。剩余的单元网格呗相应的移除。
单元网格移除
指定区域内的单元格分割
castellatedMeshControls中的refinementRegions子字典包含细化几何子字典中指定的卷区域的条目。对每个区域应用一种细化模式,可以是:
21. inside 细化内部区域;
22. outside细化体积外区域
23. distance 根据到表面的距离进行细化;并可以在多个距离上容纳不同层次与层次关键字。
对于refinementRegions,细化水平通过levels来定义格式为( )。在inside或是outside细化中,不被要求。

refinementRegions
{
    box1x1x1
    {
        mode inside;
        levels ((1.0 4));         // refinement level 4 (1.0 entry ignored)
    }

    sphere1
    {                             // refinement level 5 within 1.0 m
        mode distance;            // refinement level 3 within 2.0 m
        levels ((1.0 5) (2.0 3)); // levels must be ordered nearest first
    }
}

在这里插入图片描述
基于局部跨度的单元格分割
还可以指定单元的细化,以保证跨越相对表面之间的跨度有指定数量的单元。此细化选项可以确保有足够的单元格来解析域的某个区域中的流,例如通过一个狭窄的管道。该方法需要提供曲面几何上的近距离数据。贴近度可以通过surfaceFeatures实用程序通过surfaceFeaturesDict文件中的以下条目来计算:

surfaces
(
    "pipeWall.obj"
);

closeness
{
    pointCloseness          yes;
}

这将紧密度数据写入一个名为pipeWall.closeness.internalPointCloseness的文件到常量/triSurface目录中。然后,通过在snappyHexMeshDict中的refinementRegions子字典中添加一个条目,可以使用闭度来进行基于广度的细化,例如:

refinementRegions
{
    pipeWall
    {
        mode insideSpan;
        levels ((1000 2));
        cellsAcrossSpan 40;
    }
}

该示例显示了pipWall内的细化区域,在该区域中,在距离管壁1000的指定距离内保证最多2级细化。基于跨度的细化,由insideSpan模式指定,使用户能够保证至少40个cellsAcrossSpan,例如横跨铁管直径。

捕捉到表面
网格化过程的下一个阶段涉及到将单元顶点移动到表面几何体上,以从网格中移除锯齿状的网格曲面。这个过程是:

  1. 将星状边界上的顶点位移到STL曲面上;
  2. 解决松弛的内部网格与最新的位移边界顶点;
  3. 找出导致网格质量参数被破坏的顶点;
  4. 从它们的初始值(1)减少这些顶点的位移,并从2重复,直到网格质量满意。

该方法使用snappyHexMeshDict中的snapControls子字典中的设置,如下所示。

  • nSmoothPatch:在找到表面对应之前的补丁平滑迭代次数(通常是3次)。

  • tolerance:被表面特征点或边缘吸引的点与局部最大边缘长度(通常为2.0)的距离之比。

  • nSolveIter:网格位移松弛迭代的次数(通常30-100)。

  • nRelaiter:捕获松弛迭代的最大次数(通常为5)。
    表面捕捉
    网格层
    在网格划分过程中有一个可选的阶段,即引入额外的六面体网格层,这些网格层对齐于边界表面
    图层增加
    添加网格层的过程包括从边界缩小现有网格并插入单元层,大致如下:

  • 该网格在与该表面法线方向上按指定的厚度从该表面向后投影; 解决松弛的内部网格与最新的投影边界顶点;

  • 检查验证标准是否满足,否则减少投影厚度并返回到2;如果验证不能满足任何厚度,不要插入层; 当验证条件满足时,插入网格层;

  • 再次检查网格;如果检查失败,层被删除,我们返回到2。

网格质量控制
meshQualityControls

  • maxNonOrtho:允许的最大非正交性(度,通常为65度)。
  • maxborderyskewness:允许的最大边界面偏斜度(通常为20)
  • maxInternalSkewness:允许的最大内部面偏斜度(通常为4)。
  • maxConcave:允许的最大凹度(通常为80)。
  • minFlatness:最小投影面积与实际面积之比(一般为0.5)
  • minTetQuality:四面体单元分解后的最低质量;当引入新的重心跟踪时,从v5.0开始,一般通过设置较大的负数来关闭,可以处理负测试。
  • minVol:最小单元锥体体积(通常为1e-13,大负数禁用)。
  • minArea:最小面部面积(通常为-1)。
  • minTwist:最小表面捻度(一般为0.05)。
    minDeterminant:最小归一化细胞行列式;1 = hex; ≤ 0 = illegal cell (typically 0.001).
    minFaceWeight: 0→0.5(通常为0.05)。
    minVolRatio: 0→1.0(通常为0.01)。
    minTriangleTwist:>0表示Fluent兼容性(通常为-1)。
    nSmoothScale:错误分布迭代的次数(通常是4次)。
    error reduction:在误差点上缩小位移的量(通常是0.75)。
    relaxed:子字典,可以包含上述关键字条目的修改值,当在添加层的过程中超过nrelaediter时使用。

2.使用SnappyHexMesh创建的网格设置和运行稳态瞬态案例

演示如何使用SnappyHexMesh创建的网格设置和运行稳态瞬态案例。展示了如何动态地绘制残差,以及如何创建一个函数对象来绘制壁面剪应力。
链接: https://www.youtube.com/watch?v=ObsFQUiVi1U&t=101s

代码如下(示例):

Procedure for Meshing and Running simpleFoam in Parallel with snappyHexMesh (SHMesh)


(replace the number “8” with how ever many cores you have & make sure your decomposeParDict matches)


----------------------------------------------------------------------
1 Rename 0 folder 0.org                This prevents SHMesh interfering with it
2 <blockMesh>                    Creates background mesh for SHMesh
3 <surfaceFeatureExtract>        So the mesher knows where to snap to
4 <decomposePar>            Divides mesh into one section per CPU core
5 <mpirun -np 8 snappyHexMesh -overwrite -parallel>    Runs mesher in parallel
6 <reconstructParMesh -constant>    Puts the mesh back together again
7 delete all processor folders            Clear old mesh data
8 delete folder 0            This was a dummy folder for SHMesh
9 rename folder 0.org to 0        Reactivate the folder for the solver to use
-----------------------------------------------------------------------
10 edit the constant/polymesh/boundary file and remove all the references to patches created by blockMesh in Step2. Leave only the patches desired for the simulation to run. Edit the number at the top of the text file which shows how many patches are to be setup.
-----------------------------------------------------------------------
11 <decomposePar>            Puts the solution setup into a folder per CPU core
12 <mpirun -n 8 renumberMesh -overwrite -parallel>    Optimises the mesh
-----------------------------------------------------------------------
13 <mpirun -np 8 simpleFoam -parallel>    Run the solver in parallel


If you have GNUPLOT, NUMPY and PYFOAM installed you can plot residuals on the fly:
13 <pyFoamPlotRunner.py mpirun -np 8 simpleFoam -parallel>
----------------------------------------------------------------------   
14 <reconstructPar -latestTime>        Puts the CPU results back together into one
14b <reconstructPar>                    As #14 but if running a transient solver    


15 <paraFoam>                Launches ParaVIEW to see the results
----------------------------------------------------------------------
<type text inside the arrows into the command line but don’t type the arrows !>
----------------------------------------------------------------------

所有.stl文件加载
在这里插入图片描述
stl文件单位转换

surfaceTransformPoints -scale '(0.001 0.001 0.001)' inlet.stl inlet_meter.stl

在这里插入图片描述在这里插入图片描述
stl文件连接

cat inlet.stl outlet.stl > merge.stl

案例文件夹:0/空文件夹,0.org/放边界条件
在这里插入图片描述
blockMeshDict

1. 坐标要大于模型
2. block的patch名称
blockMesh

在这里插入图片描述
openfoam v8 运行surfaceFeatures (v6 surfaceFeatureExtract)
将surfaceFeaturesDict放到system文件夹下面

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




surfaces
(
    "inlet.stl"
    "outlet.stl"
    "visc_main.stl"
    "visc_refine_1.stl"
    "visc_refine_2.stl"
);
extractionMethod    extractFromSurface; // extractFromFile or extractFromSurface
includedAngle       150;                // Identify a feature when angle between faces < includedAngle




subsetFeatures
{
    // Keep nonManifold edges (edges with >2 connected faces)
    nonManifoldEdges       no;




    // Keep open edges (edges with 1 connected face)
    openEdges       yes;
}




writeObj            yes;
// ************************************************************************* //

示例代码,适用于openfoam v6

surfaceFeatures

生成constant/extendedFeatureEdgeMesh
在这里插入图片描述
在这里插入图片描述
decomposePar

decompsePar

在这里插入图片描述
运行网格

mpirun -np 8 snappyHexMesh -overwrite -parallel

在这里插入图片描述
system monitor查看cpu状态
在这里插入图片描述
把网格再次拼接到一起

reconstructParMesh -constant

在这里插入图片描述
网格数据在constant/polyMesh下面,可以删除processor文件了

rm processor* -r

delete folder 0 This was a dummy folder for SHMesh
rename folder 0.org to 0 Reactivate the folder for the solver to use
在这里插入图片描述
编辑constant/polymesh/boundary文件,删除所有在Step2中由blockMesh创建的patches。只保留运行模拟所需的patches。编辑文本文件顶部的数字,显示要安装多少patches。

在这里插入图片描述
先用paraview查看一下网格结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
再确认一下0/ patch名称是不是正确的
在这里插入图片描述
在这里插入图片描述
并行运算

decomposePar
mpirun -np 8 simpleFoam -parallel

报错1:

在这里插入图片描述
在这里插入图片描述
主要还是版本原因,把教程motorbike里面的momentunTransport拷贝过来,model改为kEpsilon(由0/文件夹下内容可知)
在这里插入图片描述
报错2:
在这里插入图片描述

GENERIC TEMPLATE FOR FUNCTION OBJECTS ENTRY IN
system/controlDict




functions
{
    myFunctionObject    // user-defined name of function object entry
    {
        type                functionObjectType;
        functionObjectLibs  ("libMyFunctionObjectlib.so");
        region              defaultRegion;
        enabled             yes;
        timeStart           0;
        timeEnd             10;
        outputControl       outputTime;
        outputInterval      1;
        ...
    }
}

Custom Template for wallShearStress function object


paste this code at the end of the controlDict file in the case/system directory
------------------------------------------------------------------

functions            // Start listing function objects here
{
    wallShearStress1 // user-defined name of function object entry
    {
        type        wallShearStress;  //the official name of the utility
        //functionObjectLibs ("libutilityFunctionObjects.so");  //where the utility c++ code is
        libs ("libfieldFunctionObjects.so");
         patches     ("visc_main"      
               "visc_refine_1"  
                        "visc_refine_2");   
    }    
}

报错3:
在这里插入图片描述

debug进行时


总结

以上内容为小白openfoam成长之路——snappyHexMesh

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐