# Access the mesh elements

Every function available in the API is well documented in the file `gmsh.py`. Here some of these functions are detailed with some examples. Actually, definition shown here are (truncated) copy/paste from the official documentation.
I also remind you that in VSCode (+ Python extension), the definition of the function are displayed in the text editor: extremly convenient!

Now that you know how to generate a mesh with GMSH API, you probably wants to play with the resulting mesh. For example, if you want to program a finite element solver, you probably needs to access each elements and nodes of the mesh and compute some quantity on it. In this section, you will learn the basic functionality to do that withing Python. For Julia and C++, the syntax changes but the idea is the same.

## Reference problem

Let us consider a unit square with 0.1 as mesh size. The `Surface` has a `Physical Tag` equal to 10, the bottom boundary `Line` has `Physical Tag`=1 and the three other are regrouped in the same `Physical Tag` 2

``````# File square.py
import gmsh
import sys
gmsh.initialize(sys.argv)
gmsh.option.setNumber("General.Terminal", 1)
gmsh.option.setNumber("Mesh.CharacteristicLengthMin", 0.1);
gmsh.option.setNumber("Mesh.CharacteristicLengthMax", 0.1);
# Model
model = gmsh.model
# Rectangle of (elementary) tag 1
factory = model.occ
# Sync
factory.synchronize()
# Physical groups
# Mesh (2D)
model.mesh.generate(2)
# ==============
# Code to test mesh element access will be added here !
# ...
# ==============
#Save mesh
gmsh.write("square.msh")
# Finalize GMSH
gmsh.finalize()
``````

Running it in a terminal an opening it with GMSH should open a windows as below

``````python square.py
gmsh square.msh
``````

## Nodes

Methods to get and modify mesh element are placed in the `gmsh.model.mesh` namespace. For example, to call `getNode(12)`, you should type `gmsh.model.mesh.getNode(12)`.

### Basics

Name Definition / Remark
`getNode(tag)` Get the coordinates and the parametric coordinates (if any) of the node with tag `tag`.
Return `coord`, `parametricCoord`. Generally, the first quantity of the returned array is what you want.
`getNodes(dim=-1, tag=-1, includeBoundary=False, returnParametricCoord=True)` Get the nodes classified on the entity of dimension `dim` and tag `tag`.
Return `nodeTags`, `coord`, `parametricCoord`.
`getNodesForPhysicalGroup(dim, tag)` Get the nodes from all the elements belonging to the physical group of dimension `dim` and tag `tag`.
Return `nodeTags`, `coord`
`getNodesByElementType(elementType, tag=-1, returnParametricCoord=True)` Get the nodes classified on the entity of tag `tag`, for all the elements of type `elementType`. The other arguments are treated as in `getNodes`.
Return `nodeTags`, `coord`, `parametricCoord`.

### Example

Start from the code meshing a square that has been given above and override these line

``````# ==============
# Some portions of code will be added here !
# ...
# ==============
``````

by the following line, where we ask GMSH to first provide the tag of the nodes on `Physical Line(1)` and second, their coordinate:

``````print("Nodes tag on Physical Line 1")
print(model.mesh.getNodesForPhysicalGroup(1,1))
print("Nodes coordinates on Physical Line 1")
print(model.mesh.getNodesForPhysicalGroup(1,1))
``````

You should get the following messages (not necessarily the same number/coordinate!) in your terminal

``````Nodes tag on Physical Line 1
[ 1  6  2  7 11  9 10  8  5 12 13]
Nodes coordinates on Physical Line 1
[0.  0.  0.  0.2 0.  0.  1.  0.  0.  0.3 0.  0.  0.7 0.  0.  0.5 0.  0.
0.6 0.  0.  0.4 0.  0.  0.1 0.  0.  0.8 0.  0.  0.9 0.  0. ]
``````

## Elements

### Basics

Name Definition / Remark
`getElement(elementTag)` Get the type and node tags of the element with (elementary) tag `tag`. This is a sometimes useful but inefficient way of accessing elements, as it relies on a cache stored in the model.
Return `elementType`, `nodeTags`.
`getElements(dim=-1, tag=-1)` Get the elements classified on the (elementary) entity of dimension `dim` and (elementary) tag `tag`.
Return `elementTypes`, `elementTags`, `nodeTags`
`getElementTypes(dim=-1, tag=-1)` Get the types of elements in the (elementary) entity of dimension `dim` and (elementary) tag `tag`.
Return `elementTypes`.
`getElementsByType(elementType, tag=-1, task=0, numTasks=1)` Get the elements of type `elementType` classified on the entity of tag `tag`.
Return `elementTags`, `nodeTags`.
`getElementProperties(elementType)` Get the properties of an element of type `elementType`: its name(`elementName`), dimension (`dim`), order (`order`), number of nodes(`numNodes`), coordinates of the nodes in the reference element(`nodeCoord` vector, of length `dim` times `numNodes`) and number ofprimary (first order) nodes (`numPrimaryNodes`).
Return `elementName`, `dim`, `order`, `numNodes`, `nodeCoord`, `numPrimaryNodes`.

### Example

#### Element type

As for the node, you can copy/paste these lines before `gmsh.write("square.msh")`:

``````print("Element type of Line(1) (segment has type 1)")
print(model.mesh.getElementTypes(1,1))
print("Element type of Surface(1) (triangle has type 2)")
print(model.mesh.getElementTypes(2,1))
prop = model.mesh.getElementProperties(1)
print("Properties of a segment element (type = 1)")
print("  Element Name      : "+str(prop))
print("  Dim               : "+str(prop))
print("  Order             : "+str(prop))
print("  Num of Nodes      : "+str(prop))
print("  Node Coord        : "+str(prop))
print("  Num Prim. Nodes   : "+str(prop))
``````

You should get:

``````Element type of Line(1) (segment has type 1)

Element type of Surface(1) (triangle has type 2)

Properties of a segment element (type = 1)
Element Name      : Line 2
Dim               : 1
Order             : 1
Num of Nodes      : 2
Node Coord        : [-1.  1.]
Num Prim. Nodes   : 2
``````

#### Loop on elements

Now we want to loop on the elements composing the `Line` of elementary tag 1, and for each element, display the tag of each of its vertices (starting and ending point):

``````segments = model.mesh.getElements(1,1)
print("Segment tags composing Line(1)")
print(segments)
nodes = model.mesh.getElements(1,1)
nodes_per_elem = model.mesh.getElementProperties(1)
print("Number of nodes per segment: " +str(nodes_per_elem))
for j in range(len(segments)):
print("Element Tag("+str(segments[j])+")=["+str(nodes[2*j])+", "+str(nodes[2*j+1])+"]")
``````

And this gives the following result (again, indices can differ on your side)

``````Segment tags composing Line(1)
[ 1  2  3  4  5  6  7  8  9 10]
Number of nodes per segment: 2
Element Tag(1)=[1, 5]
Element Tag(2)=[5, 6]
Element Tag(3)=[6, 7]
Element Tag(4)=[7, 8]
Element Tag(5)=[8, 9]
Element Tag(6)=[9, 10]
Element Tag(7)=[10, 11]
Element Tag(8)=[11, 12]
Element Tag(9)=[12, 13]
Element Tag(10)=[13, 2]
``````

### Integration points, jacobian, FEM basis functions, …

Numerous useful functions are provided by GMSH API, even Lagrange (and their Gradient) basis function.

## Physical entities to Elementary entities

### Basics

Name Definition / Remark
`getPhysicalGroups(dim=-1)` Get all the physical groups in the current model. If dim’ is >= 0, return only the entities of the specified dimension.
Return `dimTags`.
`getEntitiesForPhysicalGroup(dim, tag)` Get the tags of the model entities making up the physical group of dimension `dim` and tag `tag`.
Return (elementary) `tags`

### Example

This portion of codes loops on each `Physical` entities and for each of them, display every `Elementary` entities and the type of elements that is used to describe them:

``````# taken from /demos/api/poisson.py
vGroups = model.getPhysicalGroups()
for iGroup in vGroups:
dimGroup = iGroup # 1D, 2D or 3D
tagGroup = iGroup
namGroup = model.getPhysicalName(dimGroup, tagGroup)
vEntities = model.getEntitiesForPhysicalGroup(dimGroup, tagGroup)
for tagEntity in vEntities:
dimEntity = dimGroup
vElementTypes = model.mesh.getElementTypes(dimEntity,tagEntity)
print("Physical Tag="+str(tagGroup)+", Entity Tag="+str(tagEntity)+", Element Type="+str(vElementTypes))
``````

On my computer, this gives the following result

``````Physical Tag=1, Entity Tag=1, Element Type=
Physical Tag=2, Entity Tag=2, Element Type=
Physical Tag=2, Entity Tag=3, Element Type=
Physical Tag=2, Entity Tag=4, Element Type=
Physical Tag=10, Entity Tag=1, Element Type=
``````