The MMJMesh Library

Minh’s and Matthias’ Julia Mesh Library

Author

Matthias Baitsch

1 Introduction

The MMJMesh library is intended to become a simple yet versatile basis for the implementation of finite element methods or postprocessing tools. At the moment it is in a very early stage of development.

1.1 Demo for 1D meshes

First, we need to load the required modules. Note that CairoMakie included by import and not by using in order to avoid name collissions.

In the simplest case, a 1D mesh is defined by parameter bounds and the number of elements.

m = Mesh(0 .. 8, 4)
mplot(m) |> mconf()

Elements of the mesh can be easily processed in a loop:

for e  elements(m)
    println(e, " with n = ", nodeindices(e), " and l = ", length(e))
end
MMJMesh.Meshes.Edge(1)[1, 2] with n = [1, 2] and l = 2.0
MMJMesh.Meshes.Edge(2)[2, 3] with n = [2, 3] and l = 2.0
MMJMesh.Meshes.Edge(3)[3, 4] with n = [3, 4] and l = 2.0
MMJMesh.Meshes.Edge(4)[4, 5] with n = [4, 5] and l = 2.0

Various functions like nodeindices and length exist to access properties. If you are used to an object-oriented language like Java it might be helpful to understand that nodeindices(e) in Julia is equivalent to e.nodeindices() in an OO language.

Node coordinates are retrieved using the coordinates method:

coordinates(m)
2×5 Matrix{Float64}:
 0.0  2.0  4.0  6.0  8.0
 0.0  0.0  0.0  0.0  0.0

Properties are associated with the mesh using the data field of the mesh and a name for the property in the form :name

setdata!(m, :foo, 99)
setdata!(m, :bar, sqrt)

and then are ready to be used in a later stage

f = data(m, :bar)
f(4)
2.0

In Julia, :name is called a symbol. In many applications, this is equivalent to the use of strings like "name", however, easier to type.

It is easy to plot quantities for nodes

mplot(m, -1 .+ 2 * rand(nnodes(m))) |> mconf()

constant on elements

mplot(m, -1 .+ 2 * rand(nelements(m))) |> mconf()

linear on elements

mplot(m, -1 .+ 2 * rand(2, nelements(m))) |> mconf()

functions on elements

mplot(m, [Polynomial(rand(-1 .. 1, 4), IHat) for _  1:nelements(m)]) |> mconf()

Furthermore, 1D meshes can be created with a parametric function

m = Mesh(0 .. 5, 60, t -> [t; 0.3 * sin(π * t)])
mplot(m) |> mconf()

where the last parameter t -> [t; sin(t)] (read: t is mapped on the vector (t, sin(t))) defines the parametric curve

\[ \mathbf{u}(t) = \left( \begin{array}{c} t \\ \sin(t) \end{array} \right). \]

1.2 Demo for 2D meshes

Create mesh on rectangular grid

a = 80
m = Mesh((0 .. 9.0) × (0 .. 4.5), 2a, a)
mplot(m) |> mconf()

Mesh with coordinate transformation

cartesianfrompolar(x) = x[1] * [cos(x[2]), sin(x[2])]
m = Mesh((1 .. 2) × (0 .. (3 / 2)π), 10, 70, gmap=cartesianfrompolar)
mplot(m, edgesvisible=true) |> mconf()

Read mesh from Gmsh

m = Mesh(meshpath("advanced.msh"))
mplot(m) |> mconf()