OpenFoam导入gmesh二维网格

http://openfoamwiki.net/index.php/2D_Mesh_Tutorial_using_GMSH

以下所有翻译自上链接,穿插一点自己的浅薄理解

OpenFoam版本2.3.0   gmesh版本4.1.0

(OpenFoam师兄祖传代码比较老,没空升级,先试着再说。)

创建本教程是为了说明如何使用GMSH开源网格生成器为OpenFOAM生成2D网格。 默认情况下,OpenFOAM仅适用于3D网格元素,因此需要应用一些特殊步骤来创建2D网格。 这并不是GMSH或OpenFOAM的教程,只是让两个工具协同工作的一些有用步骤。 请注意,显示了两种几何生成方法。 一个使用GMSH GUI来创建几何体,并需要对生成的几何体(.geo)文件进行一些修改。 另一个直接创建几何文件。 网格化可以在两种方式中使用或不使用GUI来完成。

1.在Gmesh中定义好几何和网格

1.1图形用户界面(GUI)和* .geo-modification1.打开GMSH并创建一个新文件。

2.在单个平面(2D)中,首先创建所有点,然后将这些点组合成线,然后将线组合成曲面,从而创建几何体。这些都可以通过Elementary entity-> Add-> New下的Geometry Menu完成。

3.通过选择Geometry菜单下的Elementary entities-> Extrude-> Translate,将最终曲面拉伸为3D。选择“曲面”,然后在查看器中单击曲面。这将把表面扩展到3D空间。扩展的距离和方向在“翻译”选项卡下显示的“上下文几何定义”窗口下定义。

4.现在形状是3D,可以定义边界。要定义边界,请从“Geometry”转到Physical Groups->Add->Surface,然后添加将成为边界的每个曲面。记住边界的顺序,因为GMSH GUI将用数字标记它们,以后需要将其更改为OpenFOAM的文本名称。例如,如果形状是正方形,请选择底部,左侧,顶部,右侧,前面和后面,并将它们分别添加为物理组(如果边界由多个面组成,则可以一起选择它们然后添加物理组)。稍后,名称将从数字更改为“底部”,“左侧”,“顶部”等......这些名称将在OpenFOAM中使用。

5.还必须命名几何体的体。从Geometry中选择Physical Groups-> Add-> Volume并选择体。

6.几何应自动保存为.geo文件,但如果没有,请立即保存。然后在文本编辑器中打开.geo文件。将Physical Surfaces重命名为将在OpenFOAM中使用的名称作为边界名称。您还可以将内部曲面指定给物理曲面,以在几何体中创建内部墙。例如(数字可能不同):

  Physical Surface("front") = {28};
  Physical Surface("back") = {6};
  Physical Surface("bottom") = {27};
  Physical Surface("left") = {15};
  Physical Surface("top") = {19};
  Physical Surface("right") = {23};

对于体应该同样处理:

Physical Volume("internal") = {1};

7.在.geo文件中,必须修改Extrude语句来使得网格是单层的,然后应reconbined。 通过将Layers{1}Recombine命令添加到Extrude命令来执行此操作。 这确保了网格块仅在2D中创建,然后扩展到3D,而不是在第3轴中划分。 例如:

 Extrude {0, 0, 10} {
    Surface{6};
    Layers{1};
    Recombine;
  }

8.将.geo文件保存在文本编辑器中,然后使用Geometry菜单下的Reload在GMSH中重新加载。 GMSH不应产生任何错误。

下面是一个简单方形的2D网格.geo文件的示例:

Point(1) = {-100, 100, 0, 1e+22};
  Point(2) = {100, 100, 0, 1e+22};
  Point(3) = {100, -100, 0, 1e+22};
  Point(4) = {-100, -100, 0, 1e+22};
  Line(1) = {1, 2};
  Line(2) = {2, 3};
  Line(3) = {3, 4};
  Line(4) = {4, 1};
  Line Loop(6) = {4, 1, 2, 3};
  Plane Surface(6) = {6};
  Physical Volume("internal") = {1};
  Extrude {0, 0, 10} {
   Surface{6};
   Layers{1};
   Recombine;
  }
  Physical Surface("front") = {28};
  Physical Surface("back") = {6};
  Physical Surface("bottom") = {27};
  Physical Surface("left") = {15};
  Physical Surface("top") = {19};
  Physical Surface("right") = {23};

9.通过从“网格”菜单中选择3D,在GMSH中创建网格。 您也可以从命令行执行此操作:gmsh -3 <fileName> .geo,它将自动在同一目录中生成fileName.msh文件。 如果一切设置正确(通过挤压修改),3D网格的边应该只有连接正面和背面的直线。 这对于OpenFOAM是必需的,因为对于2D分析,网格块应该仅在两个维度上改变。 如果网格不满足此要求,OpenFOAM将产生错误。

可以通过在Options窗口中的Mesh下设置Element Size Factor来控制网格元素的大小(从主菜单中选择Tools->Options)。 数字越小,网格尺寸越小。 要进行单元大小因子的更改,只需返回Geometry,Reload,然后返回Mesh并单击3D。

10.通过从Mesh菜单中选择“保存”来保存网格。 这将使用与.geo文件相同的名称创建一个文件,但以.msh结尾。 这将由OpenFOAM附带的OpenFOAM实用程序gmshToFoam使用。

1.2从头开始创建* .geo

您也可以在任何编辑器中从头开始创建* .geo文件,而不是通过GUI创建几何体。(因为gmesh自带后台脚本,你也可以不用用鼠标在GUI界面点点点可以直接通过把脚本写好生成几何图形

1.在您选择的编辑器中,创建一个带.geo文件扩展名的新文件。

2.使用以下语法定义2D几何体。

    Point(<pointNr>) = {<x>, <y>, <z>, <cellSize>};
    Line(<lineNr>) = {<startPointNr>, <endPointNr>};
    Line Loop(<lineLoopNr>) = {(+/-)<lineNr1>, (+/-)<lineNr2>, ...};
    Plane Surface(<surfaceNr>) = {<lineLoopNr>};

请注意,Line Loop功能需要排序输入。 相邻线的末端和起点必须匹配,方向(例如顺时针)必须一致。 线的方向可以用减号反转。

请注意,线环中线条的出现顺序将在挤出后再次使用。

3.拉伸面可使用:

 surfaceVector[] = Extrude {<x>, <y>, <z>} {
 Surface{<surfaceNr>};
 Layers{1};          // create only one layer of elements in the direction of extrusion
 Recombine;};        // recombine triangular mesh to quadrangular mesh

layers{1}里的1是指在拉伸方向只拉伸一层;reconmbine是将三角网格变成四边网格

其中surfaceVector[]是一个vector容器

     surfaceVector [0] =相对平面的surfaceNumber
     surfaceVector [1] = volume Volume的数量
     surfaceVector [...] =表面周围表面的数量,与行循环中的顺序相同

4.使用以下语法定义物理以供以后用作边界

    Physical Surface("<boundaryName>") = {<surfaceNr>}
    Physical Surface("<boundaryName>") = surfaceVector[<integerAsShownAbove>];
    Physical Volume("<interiorName>") = surfaceVector[1];

5.为参数化网格定义变量

    squareSide = 200; //m
    meshThickness = squareSide / 10; 
    gridsize = squareSide / 20;

6. * .geo文件现在应该与此示例类似

// Inputs
    squareSide = 200; //m
    meshThickness = squareSide / 10; 
    gridsize = squareSide / 20;
 
    // All numbering counterclockwise from bottom-left corner
    Point(1) = {-squareSide/2, -squareSide/2, 0, gridsize};
    Point(2) = {squareSide/2, -squareSide/2, 0, gridsize};
    Point(3) = {squareSide/2, squareSide/2, 0, gridsize};
    Point(4) = {-squareSide/2, squareSide/2, 0, gridsize};
    Line(1) = {1, 2};				// bottom line
    Line(2) = {2, 3};				// right line
    Line(3) = {3, 4};				// top line
    Line(4) = {4, 1};				// left line
    Line Loop(5) = {1, 2, 3, 4}; 	
    // the order of lines in Line Loop is used again in surfaceVector[]
    Plane Surface(6) = {5};
    
    surfaceVector[] = Extrude {0, 0, meshThickness} {
     Surface{6};
     Layers{1};
     Recombine;
    };
    /* surfaceVector contains in the following order:
    [0]	- front surface (opposed to source surface)
    [1] - extruded volume
    [2] - bottom surface (belonging to 1st line in "Line Loop (6)")
    [3] - right surface (belonging to 2nd line in "Line Loop (6)")
    [4] - top surface (belonging to 3rd line in "Line Loop (6)")
    [5] - left surface (belonging to 4th line in "Line Loop (6)") */
    Physical Surface("front") = surfaceVector[0];
    Physical Volume("internal") = surfaceVector[1];
    Physical Surface("bottom") = surfaceVector[2];
    Physical Surface("right") = surfaceVector[3];
    Physical Surface("top") = surfaceVector[4];
    Physical Surface("left") = surfaceVector[5];
    Physical Surface("back") = {6}; // from Plane Surface (6) ...
    
    /* On my PC, the file must end with a free line to avoid errors which might come from different control characters in UNIX, Mac and Windows! Just to be save, insert one line below this comment!*/

7.使用GUI或命令行对* .geo-File进行网格化,如上一章所示。

1.3可选:结构化网格

有几种方法可以在GMSH中获得结构化网格。 简单几何的一种简单方法是添加:

    Transfinite Surface{<surfaceNr>}={<edgePointsNr1>, <edgePointsNr2>, ...};
    // forces later meshing to contain structured triangles
    // e.g. Transfinite Surface{6} = {1,2,3,4};
    
    Recombine Surface{<surfaceNr>};
    //combine triangles to quadrangles
    // e.g.Recombine Surface{6};

就在* .geo文件中的extrusion命令之前。

例如:

 // Inputs
	squareSide = 200; //m
	meshThickness = squareSide / 10; 
	gridsize = squareSide / 10;
 
        // Geometry
	Point(1) = {-squareSide/2, -squareSide/2, 0, gridsize};
	Point(2) = {squareSide/2, -squareSide/2, 0, gridsize};
	Point(3) = {squareSide/2, squareSide/2, 0, gridsize};
	Point(4) = {-squareSide/2, squareSide/2, 0, gridsize};
	Line(1) = {1, 2};				// bottom line
	Line(2) = {2, 3};				// right line
	Line(3) = {3, 4};				// top line
	Line(4) = {4, 1};				// left line
	Line Loop(5) = {1, 2, 3, 4}; 	
	Plane Surface(6) = {5};
 
        //Transfinite surface:
	Transfinite Surface {6};
	Recombine Surface {6};
 
	surfaceVector[] = Extrude {0, 0, meshThickness} {
	 Surface{6};
	 Layers{1};
	 Recombine;
	};
	 surfaceVector contains in the following order:
	[0]	- front surface (opposed to source surface)
	[1] - extruded volume
	[2] - bottom surface (belonging to 1st line in "Line Loop (6)")
	[3] - right surface (belonging to 2nd line in "Line Loop (6)")
	[4] - top surface (belonging to 3rd line in "Line Loop (6)")
	[5] - left surface (belonging to 4th line in "Line Loop (6)") 
	Physical Surface("front") = surfaceVector[0];
	Physical Volume("internal") = surfaceVector[1];
	Physical Surface("bottom") = surfaceVector[2];
	Physical Surface("right") = surfaceVector[3];
	Physical Surface("top") = surfaceVector[4];
	Physical Surface("left") = surfaceVector[5];
	Physical Surface("back") = {6};

2将网格转换为OpenFOAM

1.必须已经创建了一个带有controlDict文件的OpenFOAM案例目录。 将.msh文件复制到案例目录中。

2.打开命令控制台并转到案例目录,然后输入gmshToFoam <file.msh>。 例如:

gmshToFoam square.msh

这将在constant/ polyMesh目录下创建OpenFOAM使用的网格。 如果有任何错误,请确保设置了正确的案例目录(请参阅OpenFOAM文档,或使用预先发布的案例目录,如icoFoam或simpleFoam)。 如果错误表明不存在3D元素,或者存在其他网格问题,请确保在本教程的GMSH部分中遵循所有步骤。

3.通过从控制台运行checkMesh,检查网格是否符合OpenFOAM标准。

4.要确认boundary是否为OpenFOAM网格,请在constant

/ polyMesh下的case目录中打开边界文件。 每个边界都在这里定义。 对于沿第3维的面,将类型设置为“空”。 您还可以使用Contrib modifyPatches来自动执行该操作。 例如:

back
  {
    type          empty;
    nFaces        2858;
    startFace     4217;
  }
  front
  {
    type          empty;
    nFaces        2858;
    startFace     7075;
  }

这将向OpenFOAM表明这是2D案例。 确保存在GMSH .geo文件中定义的所有其他边界作为物理表面。 也可能有一个defaultFaces边界应该有nFaces = 0(不清楚如果nFaces不为0会发生什么):

defaultFaces
  {
    type          patch;
    nFaces        0;
    startFace     10073;
  }

或者,您可以在shell或shell脚本中使用awk命令编辑constant/ polyMesh / boundary字典。

$ awk -v RS="\0" -v ORS="" '{ gsub(/(patch name 1)\n    {\n        type            patch/, "(patch name 1)\n    {\n        type            (geometric patch type)"); print }' constant/polyMesh/boundary > tmp  
$ mv tmp constant/polyMesh/boundary
$ awk -v RS="\0" -v ORS="" '{ gsub(/(patch name 2)\n    {\n        type            patch/, "(patch name 2)\n    {\n        type            (geometric patch type)"); print }' constant/polyMesh/boundary > tmp  
$ mv tmp constant/polyMesh/boundary
   ...
$ awk -v RS="\0" -v ORS="" '{ gsub(/(patch name n)\n    {\n        type            patch/, "(patch name n)\n    {\n        type            (geometric patch type)"); print }' constant/polyMesh/boundary > tmp 
$ mv tmp constant/polyMesh/boundary

请注意,空格或制表符(\ t符号)的数量对于gsub(输入,输出)很重要,以查找必须更改的内容。 您还可以使用后缀命名所有相同类型的边界(例如surf1_wall,surf2_wall,surf3_empty ......),并且awk将替换找到此模式(例如_wall,_empty,_symmetry ...)的所有部分。

5.要生成internal wall,您需要从“constant / polyMesh / boundary”中删除零大小的patches,并在文件末尾添加两个零大小的patch并命名为internalWallMaster和internalWallSlave。并更新patch的总数(您可以使用 Contrib modifyPatches自动化)然后使用splitMesh在internalWall处剪切网格。 如果您有多个internal wall,请使用splitMeshWithSets。 在导入具有intenalWall的流畅网格时可以找到更多细节。
6.现在,OpenFOAM可以使用2D网格。 确保初始条件文件中的边界名称(例如p,U等等)与边界文件中的边界名称相匹配。 对于empty faces(第三维),在这些文件中将边界类型设置为empty。

7.如果一切顺利,OpenFOAM应该能够将新网格用于2D情况。 如果事情进展不顺利...... OpenFOAM会告诉你。(翻到这里我有点难受。。。

3个网格示例
3.1 2D平面对称性狭道

 /*
	Profile of the axisymmetric stenosis following a cosine
	function dependent on the axial coordinate x [1].
 
	 f(x) = R * (1 - f0/2 *(1 + Cos(2.0*Pi * (x-x0)/L) )
	 -- x0 maximum stenosis position.
	 -- L stenosis length.
	 -- R vessel radius
	 -- f0 obstruction fraction, ranging 0--1.
	 
	References:
 
	[1] Varghese, S. S., Frankel, S. H., Fischer, P. F., 'Direct numerical simulation of steotic flows. Part 1. Steady flow', Journal of Fluid Mechanics, vol. 582, pp. 253 - 280.
	*/
 
	ls = 5;
 
	Xi = 100; // um
	Xo = 100; // um
	L = 100.0; // um
 
	x0 = Xi + L/2.0;
	R = 50.0;   // um
	f0 = 0.5;   // 0--1
 
	Z = 5;
 
	Point(1) = {0, 0, 0, ls};
	Point(2) = {Xi, 0, 0, ls};
	Point(3) = {Xi, R, 0, ls};
	Point(4) = {0, R, 0, ls};
 
	Point(5) = {Xi + L, 0, 0, ls};
	Point(6) = {Xi + L + Xo, 0, 0, ls};
	Point(7) = {Xi + L + Xo, R, 0, ls};
	Point(8) = {Xi + L, R, 0, ls};
 
	Line(1) = {1, 2};
	Line(2) = {2, 3};
	Line(3) = {3, 4};
	Line(4) = {4, 1};
 
	Line(5) = {5, 6};
	Line(6) = {6, 7};
	Line(7) = {7, 8};
	Line(8) = {8, 5};
 
	Line(9) = {2, 5};
 
	pList[0] = 3; // First point label
	nPoints = 21; // Number of discretization points (top-right point of the inlet region)
	For i In {1 : nPoints}
	  x = Xi + L*i/(nPoints + 1);
	  pList[i] = newp;
	  Point(pList[i]) = {x,
	                ( R * (1 - f0/2 *(1 + Cos(2.0*Pi * (x-x0)/L) ) )),
	                0,
	                ls};
	EndFor
	pList[nPoints+1] = 8; // Last point label (top-left point of the outlet region)
 
	Spline(newl) = pList[];
 
 
	Transfinite Line {9, 10} = Ceil(L/ls) Using Progression 1;
	Transfinite Line {4, -2, 8, -6} = Ceil(R/ls) Using Progression 1.1;
	Transfinite Line {1, 3} = Ceil(Xi/ls) Using Progression 1;
	Transfinite Line {5, 7} = Ceil(Xo/ls) Using Progression 1;
 
	Line Loop(11) = {4, 1, 2, 3};
	Plane Surface(12) = {11};
	Line Loop(13) = {2, 10, 8, -9};
	Plane Surface(14) = {13};
	Line Loop(15) = {8, 5, 6, 7};
	Plane Surface(16) = {15};
	Transfinite Surface {14,12,16};
	Recombine Surface {14,12,16};
 
	Extrude {0,0,Z} {
	  Surface{14,12,16}; Layers{1}; Recombine;
	}
	Coherence;
 
	Physical Surface("symmetryLine") = {51, 37, 73};
	Physical Surface("frontAndBack") = {60, 38, 82, 16, 14, 12};
	Physical Surface("wall") = {59, 29, 81};
	Physical Surface("inlet") = {47};
	Physical Surface("outlet") = {77};
	Physical Volume("volume") = {2, 1, 3};

猜你喜欢

转载自blog.csdn.net/weixin_40501169/article/details/86495636