|
Gmsh 生成非结构网格详解(之一)
在流体计算中,我们经常要生成二维非结构网格。利用Gmsh软件可以快速生成,我们下面可以看一个例子,例子在gmsh的tutorial目录中:
下面是 t4.geo的完整说明,由于图片发不上来,只能说过程。
// 先定义几个特征长度:
lcar1 = .1;
lcar2 = .0005;
lcar3 = .075;
// 为了能够不修改文件,而全局的改变这些长度,我们能够在
// 命令行指定一个因子或者指定 Mesh.CharacteristicLengthFactor
// 选项来达成。例如
//
// $ gmsh t5 -clscale 1
//
// 将会产生一个大约两千个节点和一万个四面体的网格(在一台
// 666M 主频的 Alpha Workstation 上需要约 3 秒钟)。而
//
// $ gmsh t5 -clscale 0.2
//
// 会将所有的特征长度都缩小 5 倍,得到的网格将有大约 17 万
// 个节点,和大约 100 万个四面体,在同样的机器上,这需要花
// 费大约 16 分钟的时间,Gmsh 还需要很多改进来达到更高的效
// 率。
Point(1) = {0.5,0.5,0.5,lcar2}; Point(2) = {0.5,0.5,0,lcar1};
Point(3) = {0,0.5,0.5,lcar1}; Point(4) = {0,0,0.5,lcar1};
Point(5) = {0.5,0,0.5,lcar1}; Point(6) = {0.5,0,0,lcar1};
Point(7) = {0,0.5,0,lcar1}; Point(8) = {0,1,0,lcar1};
Point(9) = {1,1,0,lcar1}; Point(10) = {0,0,1,lcar1};
Point(11) = {0,1,1,lcar1}; Point(12) = {1,1,1,lcar1};
Point(13) = {1,0,1,lcar1}; Point(14) = {1,0,0,lcar1};
Line(1) = {8,9}; Line(2) = {9,12}; Line(3) = {12,11};
Line(4) = {11,8}; Line(5) = {9,14}; Line(6) = {14,13};
Line(7) = {13,12}; Line(8) = {11,10}; Line(9) = {10,13};
Line(10) = {10,4}; Line(11) = {4,5}; Line(12) = {5,6};
Line(13) = {6,2}; Line(14) = {2,1}; Line(15) = {1,3};
Line(16) = {3,7}; Line(17) = {7,2}; Line(18) = {3,4};
Line(19) = {5,1}; Line(20) = {7,8}; Line(21) = {6,14};
Line Loop (22) = {11,19,15,18}; Plane Surface(23) = {22};
Line Loop (24) = {16,17,14,15}; Plane Surface(25) = {24};
Line Loop (26) = {-17,20,1,5,-21,13}; Plane Surface(27) = {26};
Line Loop (28) = {4,1,2,3}; Plane Surface(29) = {28};
Line Loop (30) = {7,-2,5,6}; Plane Surface(31) = {30};
Line Loop (32) = {6,-9,10,11,12,21}; Plane Surface(33) = {32};
Line Loop (34) = {7,3,8,9}; Plane Surface(35) = {34};
Line Loop (36) = {10,-18,16,20,-4,8}; Plane Surface(37) = {36};
Line Loop (38) = {-14,-13,-12,19}; Plane Surface(39) = {38};
// 除了使用文件包含机制以外,我们还能定义函数。在下面的函数中,
// 我们使用了保留词 'newp',这样能够自动的选择一个新的点数。这
// 个数是当前最大数加一得到的。相似的,'newreg' 保留词是所有除
// 去点以外的实体数中最大的加一。
//
// 这里还没有局部变量,在将来的版本中,我们会加入相应的功能。
Function CheeseHole
p1 = newp; Point(p1) = {x, y, z, lcar3} ;
p2 = newp; Point(p2) = {x+r,y, z, lcar3} ;
p3 = newp; Point(p3) = {x, y+r,z, lcar3} ;
p4 = newp; Point(p4) = {x, y, z+r,lcar3} ;
p5 = newp; Point(p5) = {x-r,y, z, lcar3} ;
p6 = newp; Point(p6) = {x, y-r,z, lcar3} ;
p7 = newp; Point(p7) = {x, y, z-r,lcar3} ;
c1 = newreg; Circle(c1) = {p2,p1,p7};
c2 = newreg; Circle(c2) = {p7,p1,p5};
c3 = newreg; Circle(c3) = {p5,p1,p4};
c4 = newreg; Circle(c4) = {p4,p1,p2};
c5 = newreg; Circle(c5) = {p2,p1,p3};
c6 = newreg; Circle(c6) = {p3,p1,p5};
c7 = newreg; Circle(c7) = {p5,p1,p6};
c8 = newreg; Circle(c8) = {p6,p1,p2};
c9 = newreg; Circle(c9) = {p7,p1,p3};
c10 = newreg; Circle(c10) = {p3,p1,p4};
c11 = newreg; Circle(c11) = {p4,p1,p6};
c12 = newreg; Circle(c12) = {p6,p1,p7};
// 下面我们定义了一些约束曲面:
l1 = newreg; Line Loop(l1) = {c5,c10,c4}; Ruled Surface(newreg) = {l1};
l2 = newreg; Line Loop(l2) = {c9,-c5,c1}; Ruled Surface(newreg) = {l2};
l3 = newreg; Line Loop(l3) = {-c12,c8,c1}; Ruled Surface(newreg) = {l3};
l4 = newreg; Line Loop(l4) = {c8,-c4,c11}; Ruled Surface(newreg) = {l4};
l5 = newreg; Line Loop(l5) = {-c10,c6,c3}; Ruled Surface(newreg) = {l5};
l6 = newreg; Line Loop(l6) = {-c11,-c3,c7}; Ruled Surface(newreg) = {l6};
l7 = newreg; Line Loop(l7) = {c2,c7,c12}; Ruled Surface(newreg) = {l7};
l8 = newreg; Line Loop(l8) = {-c6,-c9,c2}; Ruled Surface(newreg) = {l8};
// 曲面上的网格是通过将二维的网格投影到曲面的平均曲面上得到
// 的,这样只有当曲率很小的时候才能够得到比较好的效果,否则
// 的话,您需要将曲面手工分成很小的小片。
// 变量数组能够和变量一样进行操作。注意:对于一个没有初始化
// 的变量的读写会产生不可预知的结果。数组中的所有元素能够同
// 时初始化,如 l[]={1,2,7}。
theloops[t] = newreg ;
Surface Loop (theloops[t]) = {l8+1, l5+1, l1+1, l2+1, -(l3+1), -(l7+1), l6+1, l4+1};
thehole = newreg ;
Volume(thehole) = theloops[t] ;
Return
x = 0 ; y = 0.75 ; z = 0 ; r = 0.09 ;
// 这里使用一个 For 循环来产生立方体中的五个洞:
For t In {1:5}
x += 0.166 ;
z += 0.166 ;
// 调用函数