Tutorial 4

Holes in surfaces, annotations, entity colors

import gmsh
gmsh.initialize()
gmsh.model.add("t4")
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
0.003
function hypot(a, b)
    return sqrt(a * a + b * b)
end
hypot (generic function with 1 method)
ccos = (-h5*R1 + e2 * hypot(h5, hypot(e2, R1))) / (h5*h5 + e2*e2)
ssin = sqrt(1 - ccos*ccos)
0.9119702176296789

We start by defining some points and some lines. To make the code shorter we can redefine a namespace:

factory = gmsh.model.geo
factory.addPoint(-e1-e2, 0    , 0, Lc1, 1)
factory.addPoint(-e1-e2, h1   , 0, Lc1, 2)
factory.addPoint(-e3-r , h1   , 0, Lc2, 3)
factory.addPoint(-e3-r , h1+r , 0, Lc2, 4)
factory.addPoint(-e3   , h1+r , 0, Lc2, 5)
factory.addPoint(-e3   , h1+h2, 0, Lc1, 6)
factory.addPoint( e3   , h1+h2, 0, Lc1, 7)
factory.addPoint( e3   , h1+r , 0, Lc2, 8)
factory.addPoint( e3+r , h1+r , 0, Lc2, 9)
factory.addPoint( e3+r , h1   , 0, Lc2, 10)
factory.addPoint( e1+e2, h1   , 0, Lc1, 11)
factory.addPoint( e1+e2, 0    , 0, Lc1, 12)
factory.addPoint( e2   , 0    , 0, Lc1, 13)
13
factory.addPoint( R1 / ssin, h5+R1*ccos, 0, Lc2, 14)
factory.addPoint( 0        , h5        , 0, Lc2, 15)
factory.addPoint(-R1 / ssin, h5+R1*ccos, 0, Lc2, 16)
factory.addPoint(-e2       , 0.0       , 0, Lc1, 17)
17
factory.addPoint(-R2 , h1+h3   , 0, Lc2, 18)
factory.addPoint(-R2 , h1+h3+h4, 0, Lc2, 19)
factory.addPoint( 0  , h1+h3+h4, 0, Lc2, 20)
factory.addPoint( R2 , h1+h3+h4, 0, Lc2, 21)
factory.addPoint( R2 , h1+h3   , 0, Lc2, 22)
factory.addPoint( 0  , h1+h3   , 0, Lc2, 23)
23
factory.addPoint( 0, h1+h3+h4+R2, 0, Lc2, 24)
factory.addPoint( 0, h1+h3-R2,    0, Lc2, 25)
25
factory.addLine(1 , 17, 1)
factory.addLine(17, 16, 2)
2

Gmsh provides other curve primitives than straight lines: splines, B-splines, circle arcs, ellipse arcs, etc. Here we define a new circle arc, starting at point 14 and ending at point 16, with the circle's center being the point 15:

factory.addCircleArc(14,15,16, 3)
3

Note that, in Gmsh, circle arcs should always be smaller than Pi. The OpenCASCADE geometry kernel does not have this limitation.

We can then define additional lines and circles, as well as a new surface:

factory.addLine(14,13, 4)
factory.addLine(13,12, 5)
factory.addLine(12,11, 6)
factory.addLine(11,10, 7)
factory.addCircleArc(8,9,10, 8)
factory.addLine(8,7, 9)
factory.addLine(7,6, 10)
factory.addLine(6,5, 11)
factory.addCircleArc(3,4,5, 12)
factory.addLine(3,2, 13)
factory.addLine(2,1, 14)
factory.addLine(18,19, 15)
factory.addCircleArc(21,20,24, 16)
factory.addCircleArc(24,20,19, 17)
factory.addCircleArc(18,23,25, 18)
factory.addCircleArc(25,23,22, 19)
factory.addLine(21,22, 20)
20

But we still need to define the exterior surface. Since this surface has a hole, its definition now requires two curves loops:

factory.addCurveLoop([17,-15,18,19,-20,16], 21)
factory.addPlaneSurface([21], 22)
factory.addCurveLoop([11,-12,13,14,1,2,-3,4,5,6,7,-8,9,10], 23)
23
factory.addPlaneSurface([23,21], 24)
24

As a general rule, if a surface has N holes, it is defined by N+1 curve loops: the first loop defines the exterior boundary; the other loops define the boundaries of the holes.

factory.synchronize()

Finally, we can add some comments by creating a post-processing view containing some strings:

v = gmsh.view.add("comments")
0

Add a text string in window coordinates, 10 pixels from the left and 10 pixels from the bottom:

gmsh.view.addListDataString(v, [10, -10], ["Created with Gmsh"])

Add a text string in model coordinates centered at (X,Y,Z) = (0, 0.11, 0), with some style attributes:

gmsh.view.addListDataString(v, [0, 0.11, 0], ["Hole"],
                            ["Align", "Center", "Font", "Helvetica"])

These annotations are handled by a list-based post-processing view. For large post-processing datasets, that contain actual field values defined on a mesh, you should use model-based post-processing views instead, which allow to efficiently store continuous or discontinuous scalar, vector and tensor fields, or arbitrary polynomial order.

Views and geometrical entities can be made to respond to double-click events, here to print some messages to the console:

gmsh.option.setString("View[0].DoubleClickedCommand",
                      "Printf('View[0] has been double-clicked!');")
gmsh.option.setString(
    "Geometry.DoubleClickedLineCommand",
    "Printf('Curve %g has been double-clicked!', Geometry.DoubleClickedEntityTag);")

We can also change the color of some entities:

gmsh.model.setColor([(2, 22)], 127, 127, 127)
gmsh.model.setColor([(2, 24)], 160, 32, 240)
gmsh.model.setColor([(1, i) for i in 1:14], 255, 0, 0)
gmsh.model.setColor([(1, i) for i in 15:20], 255, 255, 0)
gmsh.model.mesh.generate(2)
Info    : Meshing 1D...
Info    : [  0%] Meshing curve 1 (Line)
Info    : [ 10%] Meshing curve 2 (Line)
Info    : [ 10%] Meshing curve 3 (Circle)
Info    : [ 20%] Meshing curve 4 (Line)
Info    : [ 20%] Meshing curve 5 (Line)
Info    : [ 30%] Meshing curve 6 (Line)
Info    : [ 30%] Meshing curve 7 (Line)
Info    : [ 40%] Meshing curve 8 (Circle)
Info    : [ 40%] Meshing curve 9 (Line)
Info    : [ 50%] Meshing curve 10 (Line)
Info    : [ 50%] Meshing curve 11 (Line)
Info    : [ 60%] Meshing curve 12 (Circle)
Info    : [ 60%] Meshing curve 13 (Line)
Info    : [ 70%] Meshing curve 14 (Line)
Info    : [ 70%] Meshing curve 15 (Line)
Info    : [ 80%] Meshing curve 16 (Circle)
Info    : [ 80%] Meshing curve 17 (Circle)
Info    : [ 90%] Meshing curve 18 (Circle)
Info    : [ 90%] Meshing curve 19 (Circle)
Info    : [100%] Meshing curve 20 (Line)
Info    : Done meshing 1D (Wall 0.00801431s, CPU 0.008016s)
Info    : Meshing 2D...
Info    : [  0%] Meshing surface 22 (Plane, Frontal-Delaunay)
Info    : [ 50%] Meshing surface 24 (Plane, Frontal-Delaunay)
Info    : Done meshing 2D (Wall 0.0207286s, CPU 0.020712s)
Info    : 787 nodes 1633 elements
gmsh.write("t4.msh")
Info    : Writing 't4.msh'...
Info    : Done writing 't4.msh'
gmsh.finalize()

This page was generated using Literate.jl.