Grids

In order to solve a problem using the boundary element method, we must first define the grid (or mesh) on which the problem will be discretised. In Bempp, the grid will be a triangulation of a 2D surface in 3D space. Bempp currently only supports grids consisting of flat surface triangles.

This section looks at how grids can be created and used in Bempp. Full documentation of the functionality of Bempp grids can be found on Read the Docs.

Overview

A Bempp grid can be created using a built-in grid, by importing a gmsh file, or by providing the grid data.

We first import Bempp and NumPy.

import bempp.api
import numpy as np

Built-in grids

Various shapes are included in the bempp.api.shapes module, and discretisations with different numbers of elements can be created using these. In order for the these built-in grids to work, Gmsh must be installed and the command gmsh must be available in the path.

The command regular_sphere creates a sphere by refining a base octahedron. The number of elements in the sphere is given by \(8 \times 4^n\), where \(n\) is the refinement level. The following command creates a triangulation of a sphere with refinement level 3:

grid = bempp.api.shapes.regular_sphere(3)

The command sphere creates a sphere with a chosen element size. The following command creates a sphere with element diameter \(h=0.1\):

grid = bempp.api.shapes.sphere(h=0.1)

The command cube creates a cube with a chosen element size. The following command creates a cube with element diameter \(h=0.3\):

grid = bempp.api.shapes.cube(h=0.3)

Full automatically-generated documentation of Bempp’s available built-in grids can be found here.

Importing a grid

Grids can be importedusing Bempp’s import_grid command. For example, the following command will load a grid from the Gmsh file my_grid.msh.

grid = bempp.api.import_grid('my_grid.msh')

Bempp uses the file ending to recognise a number of grid formats. Importing grids is handled by the meshio library.

This works through the external meshio library. A list of all files types that can be imported can be found in the meshio documentation. Frequently used formats with Bempp are .msh (Gmsh), .vtk (Legacy VTK), and .vtu (VTK Xml Format).

Creating a grid from element data

Bempp grids can be generated from arrays containing vertex coordinates and connectivity information. For example, to create a grid consisting of two triangles with vertices \(\\{(0, 0, 0), (1, 0, 0), (0, 1, 0)\\}\) and \(\\{(1, 0, 0), (1, 1, 0), (0, 1, 0)\\}\) we use the following commands:

vertices = np.array(
    [[0, 1, 0, 1], [0, 0, 1, 1], [0, 0, 0, 0]],
    dtype=np.float64)
elements = np.array(
    [[0, 1], [1, 3], [2, 2]], dtype=np.uint32)
grid = bempp.api.Grid(vertices, elements)

Note that the three arrays in the vertices array are the \(x\)-coordinates, then the \(y\)-coordinates, then the \(z\)-coordinates. Similarly, the three arrays in the elements array are the first points of each triangle, then the second points, then the third points. In general, the vertices and elements arrays should have shapes \(3\times M\) and \(3\times N\) (respectively) for a grid with \(M\) vertices and \(N\) elements.

The array vertices contains the 3D coordinates of all vertices. The array elements contains the connectivity information. In this case the first triangle consists of the vertices 0, 1, 2, and the second triangle consists of the vertices 1, 3, 2.

Optionally, we can specify a list domain_indices that gives different groups of elements the same id. This can be used for example to generate different types of boundary data on different parts of the grid, or to specify function spaces only on parts of the grid. In this example, both triangles automatically have the identifier 0 since nothing else was specified. This is equivalent to running:

grid = bempp.api.Grid(vertices, elements, domain_indices=[0, 0])

Using Grids

Once you have created a Bempp grid, you may want to use information about your grid. This page show how commonly used information can be obtained from a Bempp grid.

Querying grid information

The number of elements, edges and vertices in a grid are given by:

grid.number_of_elements
grid.number_of_edges
grid.number_of_vertices

To query the maximum and minimum element diameter use the following attributes:

grid.maximum_element_diameter
grid.minimum_element_diameter

The vertex indices of the element 5 can be obtained using:

grid.elements[:, 5]

Note that the numbering of element starts at 0, so element 5 is the grid’s sixth element.

The vertex coordinates of element 5 can be found using:

grid.vertices[:, grid.elements[:, 5]]

The area of the element 5 is:

grid.volumes[5]

The edge indices associated with element 5 are:

grid.element_edges[5]

The vertex indices of the edges of element 5 can be obtained using:

grid.edges[:, grid.element_edges[:, 5]]

This returns a 2×3 array of the vertex coordinates associated with the three edges of the element. Edges in Bempp are ordered in the following way:

Edge

First vertex

Second vertex

0

0

1

1

0

2

2

1

2

Full automatically-generated documentation of the Bempp Grid class can be found here.

Plotting and exporting grids

To export a grid, we can use the export command:

bempp.api.export('grid.msh', grid=grid)

This commands export the object grid as Gmsh file with the name grid.msh.

In order to plot a grid, we can simply use the command:

grid.plot()

By default, this will plot using Gmsh (or plotly if you are inside a Jupyter notebook). The following command can be used to change the plotting backend.

bempp.api.PLOT_BACKEND = "gmsh"
bempp.api.PLOT_BACKEND = "paraview"

This requires Gmsh or Paraview to be available in the system path.