摘要
通过对geo文件中英文的简化翻译和实际操作体验,简要记录对Gmesh的工作方法和脚本使用方法的理解。
(主要内容在各.geo文件的注释中,耐心阅读)
t1.geo
// The simplest construction in Gmsh's scripting language is the `affectation'
// 定义一个新的变量“ lc”:
lc = 1e-2;
// 在定义点时使用该变量。分别需要三个坐标(X,Y和Z)
// 以及该点的大小的特征长度(lc)
point(1) = {0,0,0,lc};
//The distribution of the mesh element sizes is then obtained by interpolation of these characteristic lengths throughout the geometry. Another method to specify characteristic lengths is to use a background mesh (see `t7.geo' and `bgmesh.pos').
// 再定义一些点来画曲线。
// 直线需要两个点来确定,是带方向的。
// 注意线段2中点的顺序。
point(2) = {.1,0,0,lc};
point(3) = {.1,.3,0,lc};
point(4) = {0,.3,0,lc};
Line(1) = {1,2};
Line(2) = {3,2};
Line(3) = {3,4};
Line(4) = {4,1};
// 先定义线环。线环要首尾衔接,要注意线的方向。
Line Loop(1) = {4,1,-2,3};
// 此处没有孔,由单一线环构建曲面。
Plane Surface(1) = {1};
// 此时,Gmesh可以显示长方形面并网格化了。如果想将特定区域中的元素赋予编号,可以通过“physical entities”实现。
// 如下。点1和点2将保存到输出网格文件中且区域编号为1.
Physical Point(1) = {1,2};
// 线和面的物理实体集设置方法同上
// 在线1和线2上的、所有由mesh生成的线,均加入输出文件并标号2
// 在线3上的、所有由mesh生成的线,均加入输出文件并由程序自动标号(以及加标签“My second line (automatic physical id)”)
// 在面1上的、所有由mesh生成的(三角)面,均加入输出文件并由程序自动标号(以及加标签“My surface”)
MY_LINE = 2;
Physical Line(MY_LINE) = {1,2} ;
Physical Line("My second line (automatic physical id)") = {3} ;
Physical Line("My third line (physical id 5)", 5) = {4} ;
Physical Surface("My surface") = {1} ;
// 也可以直接定义几何图形(从Gmsh 3.0开始)。
// SetFactory("OpenCASCADE");
// Rectangle(1) = {1,2,3,4,5,0};
// Rectangle(2) = {1,2,3,4,5};
// Rectangle(标号) = {参数集}:1,2,3是原点坐标,4、5分别是dX和dY,0是棱角圆滑半径(可以不输入)。
// 但这样需要用户界面来获知点线面的标号。
//
// 其他案例:
// 参考tutorial / t16.geo
// 参考demos / boolean
- 主菜单栏:Tools->Options
General-Advanced:Restore all options to default settings. 可以恢复因错误设置导致的任何异常。
Geometry-Visibility:points、point Labels等,可以显示更多信息。 - 左侧栏:Modules->Geometry
Reload script:重新加载geo文件
Edit script:编辑geo文件
* 在界面上的操作都会记录到geo文件中。 - 建议使用VSCode编辑器,联网安装GEO文件扩展,可以标注关键字。注意关键字的大小写。
- geo语法与C++语法有相似之处,例如支持“++”、“+=”。可以写出类似代码
num=1; Point(num++) = {0, 0, 0, 0};
(但编写者可能因此混淆编号与具体实体间的指代关系) - 自动新增的标号=之前最大编号值+1。(点线面环体物理,六者之间的编号相互独立)
t2.geo
Include "t1.geo";
Point(5) = {0, .4, 0, lc};
Line(5) = {4, 5};
// 点3在x方向平移(translate)-0.05单位。
Translate {-0.05, 0, 0} { Point{3}; }
// 点3复制(Duplicata)并y方向平移0.1单位。
// 复制+移动得到的点,编号未知。在用户界面鼠标置于其上可显示相关信息。(由于点的编号最大为5,故该点的自动编号为6)
Translate {0, 0.1, 0} { Duplicata{ Point{3}; } }
Line(7) = {3, 6};
Line(8) = {6, 5};
Line Loop(10) = {5,-8,-7,3};
Plane Surface(11) = {10};
// 类似matlab,可以用指针接收返回值,下标同样从0开始。
// 并对返回值加以显示(点击状态栏的文字部分可以调出信息输出框)
my_new_surfs[] = Translate {0.12, 0, 0} { Duplicata{ Surface{1, 11}; } };
Printf("New surfaces '%g' and '%g'", my_new_surfs[0], my_new_surfs[1]);
// 定义体积volume需要面环surface loop(类似于定义面需要线环line loop)。
// 无孔体只需要一个面环。
Point(100) = {0., 0.3, 0.13, lc}; Point(101) = {0.08, 0.3, 0.1, lc};
Point(102) = {0.08, 0.4, 0.1, lc}; Point(103) = {0., 0.4, 0.13, lc};
Line(110) = {4, 100}; Line(111) = {3, 101};
Line(112) = {6, 102}; Line(113) = {5, 103};
Line(114) = {103, 100}; Line(115) = {100, 101};
Line(116) = {101, 102}; Line(117) = {102, 103};
Line Loop(118) = {115, -111, 3, 110}; Plane Surface(119) = {118};
Line Loop(120) = {111, 116, -112, -7}; Plane Surface(121) = {120};
Line Loop(122) = {112, 117, -113, -8}; Plane Surface(123) = {122};
Line Loop(124) = {114, -110, 5, 113}; Plane Surface(125) = {124};
Line Loop(126) = {115, 116, 117, 114}; Plane Surface(127) = {126};
Surface Loop(128) = {127, 119, 121, 123, 125, 11};
Volume(129) = {128};
// 也可以通过面的拉伸extrude来制造体积。
// 点线面等信息将自动补完。
Extrude {0, 0, 0.12} { Surface{my_new_surfs[1]}; }
// 可以对已存在点的特征长度进行修改
Characteristic Length {103, 105, 109, 102, 28, 24, 6, 5} = lc * 3;
// Note that, if the transformation tools are handy to create complex
// geometries, it is also sometimes useful to generate the `flat' geometry, with
// an explicit list of all elementary entities. This can be achieved by
// selecting the `File->Save as->Gmsh unrolled geometry' menu or by typing
//
// > gmsh t2.geo -0
//
// on the command line.
// 将129和130体积中所有mesh得到的六面体以标记1保存至输出文件。
Physical Volume ("The volume", 1) = {129,130};
t3.geo
Include "t1.geo";
// layers可以指定拉伸extrude时拉伸方向上的网格划分
// {0.5,1}:0~50%为第一层,50%~100%为第二层
// {8,2}:第一层均分8份,第二层均分2份
// 该步执行后点击边侧栏mesh->2D和3D以显示网格划分
h = 0.1;
Extrude {0,0,h} {
Surface{1}; Layers{ {8,2}, {0.5,1} };
}
// 也可以Extrude旋转拉伸
// {0,1,0}:旋转轴的轴向
// {-0.1,0,0.1}:旋转轴位置
// -Pi/2:旋转角度(右手法则为正)
Extrude { {0,1,0} , {-0.1,0,0.1} , -Pi/2 } {
Surface{28}; Layers{7}; Recombine;
}
// 还可以Extrude同时拉伸和旋转(先拉伸参数,后旋转参数)
// angle是一种参数,在GUI界面可以调整(左侧栏parameters)
// "Parameters/Twisting angle":变量在GUI左侧栏的位置
// step 1:未知
// recombine:未知
DefineConstant[ angle = {90, Min 0, Max 120, Step 1,
Name "Parameters/Twisting angle"} ];
out[] = Extrude { {-2*h,0,0}, {1,0,0} , {0,0.15,0.25} , angle * Pi / 180 } {
Surface{50}; Layers{10}; Recombine;
};
// Extrude的返回值,[0]“顶面”,[1]“生成的体积”,[2]、[3]……:生成的各个侧面
Physical Volume(101) = {1, 2, out[1]};
// 可以在脚本中设置显示参数
// 这些参数在主菜单Tools->Optional中一一对应
Geometry.PointNumbers = 1; // 显示点标号
Geometry.Color.Points = Orange; // 更改点颜色
General.Color.Text = White;
Mesh.Color.Points = {255,0,0};
// 颜色设置时,可以输入red等系统自带变量,也可以直接赋值已有颜色变量,或自己定义一种颜色
Geometry.Color.Surfaces = Geometry.Color.Points;
// 选项设置可以保存成文件,指定为默认设置等。
// 均在主菜单File中Save相关选项中。
t4.geo
cm = 1e-02;
e1 = 4.5 * cm; e2 = 6 * cm / 2; e3 = 5 * cm / 2;
h1 = 5 * cm; h2 = 10 * cm; h3 = 5 * cm; h4 = 2 * cm; h5 = 4.5 * cm;
R1 = 1 * cm; R2 = 1.5 * cm; r = 1 * cm;
Lc1 = 0.01;
Lc2 = 0.003;
// 所有的数学函数均可用(首字母大写)
// gmesh另外提供了一些函数。Hypot(a, b) := Sqrt(a^2 + b^2)
ccos = (-h5*R1 + e2 * Hypot(h5, Hypot(e2, R1))) / (h5^2 + e2^2);
ssin = Sqrt(1 - ccos^2);
Point(1) = {-e1-e2, 0 , 0, Lc1}; Point(2) = {-e1-e2, h1 , 0, Lc1};
Point(3) = {-e3-r , h1 , 0, Lc2}; Point(4) = {-e3-r , h1+r , 0, Lc2};
Point(5) = {-e3 , h1+r , 0, Lc2}; Point(6) = {-e3 , h1+h2, 0, Lc1};
Point(7) = { e3 , h1+h2, 0, Lc1}; Point(8) = { e3 , h1+r , 0, Lc2};
Point(9) = { e3+r , h1+r , 0, Lc2}; Point(10)= { e3+r , h1 , 0, Lc2};
Point(11)= { e1+e2, h1 , 0, Lc1}; Point(12)= { e1+e2, 0 , 0, Lc1};
Point(13)= { e2 , 0 , 0, Lc1};
Point(14)= { R1 / ssin, h5+R1*ccos, 0, Lc2};
Point(15)= { 0 , h5 , 0, Lc2};
Point(16)= {-R1 / ssin, h5+R1*ccos, 0, Lc2};
Point(17)= {-e2 , 0.0 , 0, Lc1};
Point(18)= {-R2 , h1+h3 , 0, Lc2}; Point(19)= {-R2 , h1+h3+h4, 0, Lc2};
Point(20)= { 0 , h1+h3+h4, 0, Lc2}; Point(21)= { R2 , h1+h3+h4, 0, Lc2};
Point(22)= { R2 , h1+h3 , 0, Lc2}; Point(23)= { 0 , h1+h3 , 0, Lc2};
Point(24)= { 0, h1+h3+h4+R2, 0, Lc2}; Point(25)= { 0, h1+h3-R2, 0, Lc2};
Line(1) = {1 , 17};
Line(2) = {17, 16};
// Gmesh提供各种曲线:
// splines样条、B-splines B样条、circle arcs 圆弧、ellipse arcs 椭圆弧
// {14,15,16}:圆心15,起点14,终点16,右手法则
// 圆弧的角度应小于π
Circle(3) = {14,15,16};
Line(4) = {14,13}; Line(5) = {13,12}; Line(6) = {12,11};
Line(7) = {11,10}; Circle(8) = {8,9,10}; Line(9) = {8,7};
Line(10) = {7,6}; Line(11) = {6,5}; Circle(12) = {3,4,5};
Line(13) = {3,2}; Line(14) = {2,1}; Line(15) = {18,19};
Circle(16) = {21,20,24}; Circle(17) = {24,20,19};
Circle(18) = {18,23,25}; Circle(19) = {25,23,22};
Line(20) = {21,22};
Line Loop(21) = {17,-15,18,19,-20,16};
Plane Surface(22) = {21};
// 构建曲面时,第一个参数是外边界,其余参数都是要被减去的内边界。
// 线环的时针方向有影响吗?不知道。
Line Loop(23) = {11,-12,13,14,1,2,-3,4,5,6,7,-8,9,10};
Plane Surface(24) = {23,21};
// 一些花里胡哨
View "comments" {
// T2函数
// 以GUI显示区左下角为原点,单位为像素。
// 第一个参数,向右为正;第二个参数,向下为正。
T2(10, -10, 0){ StrCat("Created on ", Today, " with Gmsh") };
// T3函数
// 原点坐标与显示区中的指定坐标一致。
T3(0, 0.11, 0, TextAttributes("Align", "Center", "Font", "Helvetica")){ "Hole" };
// If a string starts with `file://', the rest is interpreted as an image
// file. For 3D annotations, the size in model coordinates can be specified
// after a `@' symbol in the form `widthxheight' (if one of `width' or
// `height' is zero, natural scaling is used; if both are zero, original image
// dimensions in pixels are used):
// 图片显示失败。@0.01x0.01,黑图。
T3(0, 0.09, 0, TextAttributes("Align", "Center")){ "file://image.png@0.01x0" };
// The 3D orientation of the image can be specified by proving the direction
// of the bottom and left edge of the image in model space:
T3(-0.01, 0.09, 0, 0){ "file://image.png@0.01x0,0,0,1,0,1,0" };
// The image can also be drawn in "billboard" mode, i.e. always parallel to
// the camera, by using the `#' symbol:
T3(0, 0.12, 0, TextAttributes("Align", "Center")){ "file://image.png@0.01x0#" };
// The size of 2D annotations is given directly in pixels:
T2(350, -7, 0){ "file://image.png@20x0" };
};
// 还是花里胡哨。
// Views and geometrical entities can be made to respond to double-click events:
View[0].DoubleClickedCommand = "Printf('View[0] has been double-clicked!');";
Geometry.DoubleClickedLineCommand = "Printf('Line %g has been double-clicked!',
Geometry.DoubleClickedEntityTag);";
// We can also change the color of some mesh entities:
Color Grey50{ Surface{ 22 }; }
Color Purple{ Surface{ 24 }; }
Color Red{ Line{ 1:14 }; }
Color Yellow{ Line{ 15:20 }; }
t5.geo
- Tools->Optional,Mesh,General,Element Size Factor 即 Mesh.CharacteristicLengthFactor 可设置自动mesh时的默认网格大小
- 网格划分结果的统计可通过Tools->Statistics查看。
- 可以使用newl、news、newv、newreg来生成对应编号,分别对应线、面、体和任何非点的实体。例如
c1 = newreg; Circle(c1) =...
- 内部代码块与调用,疑似仅文本复制。
- 循环 For t In {1:5} EndFor
- 调用循环是为了画内部球。圆弧不能超过π的限制导致线环和面环的生成变得复杂。
- 带内部空洞的体,生成同样需要指定多个面环,第一个是外边界,其他是内边界。
生成带内部空洞的体积,用脚本处理比较困难,或许依靠GUI来实现比较方便。
小结:
- 基本了解Gmesh的脚本与GUI操作的对应关系
- GUI显示的相关设置
- 脚本的结构和部分语法
- 一些常用函数的用法