Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Mesh module

The mesh module defines the mesh data structure used throughout the Poisson 2D solver.
It encapsulates the geometrical discretization of the domain, i.e., the set of vertices (points in space) and the list of finite elements that connect those vertices.
Any details related to the definition of an element—such as connectivity, shape functions, or element types are implemented in element.rs and simply referenced here.

Mesh struct

The main struct in this module is Mesh2d. It holds:

  • vertices: the coordinates of all mesh nodes as a Vec<Point2<f64>>. A vector (from the std lib) of Point2<f64> vectors (from nalgebra),
  • elements: the list of finite elements as Vec<Element>,
  • element_type: an ElementType enum indicating the type of all elements in the mesh (e.g., P1, Q1).

The Element struct and ElementType enum are defined in the element.rs module.

#![allow(unused)]
fn main() {
#[derive(Clone, Debug)]
pub struct Mesh2d {
    vertices: Vec<Point2<f64>>,
    elements: Vec<Element>,
    element_type: ElementType,
}
}

This struct is marked with #[derive(Clone, Debug)] to allow duplication and debug printing, which are useful for testing and inspecting the mesh.

Mesh implementations

The implementation block provides:

  • new(...): a constructor that takes ownership of the vertex list, element list, and element type.
  • vertices(&self): returns an immutable slice of the mesh's vertices.
  • elements(&self): returns an immutable slice of the mesh's elements.
  • element_type(&self): returns a reference to the mesh's ElementType.
#![allow(unused)]
fn main() {
impl Mesh2d {
    pub fn new(
        vertices: Vec<Point2<f64>>,
        elements: Vec<Element>,
        element_type: ElementType,
    ) -> Self {
        Self {
            vertices,
            elements,
            element_type,
        }
    }
    pub fn vertices(&self) -> &[Point2<f64>] {
        &self.vertices
    }

    pub fn elements(&self) -> &[Element] {
        &self.elements
    }

    pub fn element_type(&self) -> &ElementType {
        &self.element_type
    }
}
}

These accessor methods are intentionally read-only, ensuring the internal structure of the mesh cannot be mutated from outside without explicit intent.

A simple unit test

The module includes a basic unit test to verify that:

  • The mesh stores the correct number of vertices and elements,
  • The element_type is stored and accessible correctly.

The test builds a simple unit square mesh with four vertices and one Q1 element, then asserts the expected sizes and type.

#![allow(unused)]
fn main() {
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_mesh2d() {
        let vertices = vec![
            Point2::new(0.0, 0.0),
            Point2::new(1.0, 0.0),
            Point2::new(1.0, 1.0),
            Point2::new(0.0, 1.0),
        ];
        let elements = vec![Element {
            indices: vec![0, 1, 2, 3],
        }];
        let mesh = Mesh2d {
            vertices,
            elements,
            element_type: ElementType::Q1,
        };

        assert_eq!(mesh.vertices().len(), 4);
        assert_eq!(mesh.elements().len(), 1);
        assert_eq!(*mesh.element_type(), ElementType::Q1);
    }
}
}