Version:

Salvus' UnstructuredMesh - Part 1 - Points, connectivity and fields

This tutorial focuses on the data structure of meshes in Salvus -- the UnstructuredMesh objects. It will discuss the internal workings of the UnstructuredMesh class, but it will not focus on creating meshes.
By the end of this tutorial, you will:
  • Understand the basic components of a Salvus unstructured mesh, including points, connectivity, and fields.
  • Understand the distinction between different types of fields (nodal, elemental, and elemental nodal) and how to add or remove them.
Let's look what's in a Salvus mesh!
Copy
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Line3DCollection

import salvus.namespace as sn

Prelude: on spectral elements and GLL shape functions

Before diving into Salvus unstructured meshes, it’s important to understand the role of spectral element modelling in relation to meshes. The spectral element method (SEM) is a high-order finite element method used to solve partial differential equations on unstructured meshes.
The SEM method uses meshes based on finite elements, with given Gauss-Lobatto-Legendre (GLL) points. These GLL points are specific quadrature points used within each element for numerical integration and interpolation. They allow accurate approximation of physical fields within the element. When we speak of a first order (or higher order) mesh, we refer to how many GLL points are used per element. or instance, a first-order mesh uses two GLL points per element edge, first-order (linear) polynomials between the vertices. Higher-order meshes use more, enabling greater accuracy at the cost of increased computational complexity (and higher memory usage).
Let's now explore how Salvus represents these points, elements, and fields defined over them.
In this tutorial, it is assumed you already have a mesh somehow. This can be from an external source (like an exodus or .h5 file) or from a Salvus meshing routine. For transferring meshes between scripts, to other machines, or to Mondaic for debugging, we always prefer the .h5 format.
Let's load the mesh from an .h5 file. This is an HDF5 file, but that only specifies in what format the data is stored. As HDF5 files are only data containers, the actual contents of HDF5 files is program specific, and no other program would be expected to understand these meshes without additionaly information.
mesh = sn.UnstructuredMesh.from_h5("data/block_with_hole_small.h5")
Of course, the existence of from_h5 implies the existence of its counterpart, and indeed, this is the Salvus-native way to write your mesh to a file:
mesh.write_h5(
    "data/block_with_hole_v2.h5",
)
This will write the mesh again to an HDF5 file. Additionally, it will also write an XDMF file, which can be used to open the mesh in ParaView.
We can visualize this mesh by simply leaving it at the end of a notebook cell without any other statements. This will (for any Python object) try to display it. Salvus meshes have a built-in display method for notebooks that are interactive widgets.
mesh