Skip to content
This repository was archived by the owner on Dec 2, 2025. It is now read-only.

Commit 02a0fe5

Browse files
authored
Tidy documentation (#137)
* Add script to insert links before building with --no-deps * move example from trait to SingleElementGridBuilder * add KaTeX * docs copyedit * fmt
1 parent c56e9a4 commit 02a0fe5

File tree

9 files changed

+146
-85
lines changed

9 files changed

+146
-85
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""Replace the links to other crates in documentation strings.
2+
3+
This can be run before building the docs with the `--no-deps` flag to make the links work
4+
in the generated docs
5+
"""
6+
7+
import os
8+
import re
9+
10+
11+
def _insert_doc_links(content):
12+
content = re.sub(r"(\s)\[ndelement\](\s|\n)", r"\1[ndelement](https://bempp.github.io/ndelement/rust/ndelement/)\1", content)
13+
return content
14+
15+
16+
def insert_doc_links(folder):
17+
for file in os.listdir(folder):
18+
if not file.startswith("."):
19+
file_path = os.path.join(folder, file)
20+
if os.path.isdir(file_path):
21+
insert_doc_links(file_path)
22+
elif os.path.isfile(file_path) and file.endswith(".rs"):
23+
with open(file_path) as f:
24+
content = f.read()
25+
with open(file_path, "w") as f:
26+
f.write(_insert_doc_links(content))
27+
28+
29+
root_dir = os.path.join(os.path.join(
30+
os.path.dirname(os.path.realpath(__file__)),
31+
".."), "..")
32+
insert_doc_links(os.path.join(root_dir, "src"))
33+
insert_doc_links(os.path.join(root_dir, "examples"))
34+
insert_doc_links(os.path.join(root_dir, "tests"))

.github/workflows/docs.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,15 @@ jobs:
2424
mpi: "mpich"
2525
- uses: actions/checkout@v4
2626

27+
- name: Set up Python
28+
uses: actions/setup-python@v4
29+
with:
30+
python-version: 3.14
31+
- name: Insert doc links
32+
run: python .github/scripts/insert_doc_links.py
33+
2734
- name: Build docs
28-
run: cargo +nightly doc --no-deps -Zunstable-options -Zrustdoc-scrape-examples --all-features
35+
run: RUSTDOCFLAGS="--html-in-header katex-header.html" cargo +nightly doc --no-deps -Zunstable-options -Zrustdoc-scrape-examples --all-features
2936

3037
- name: Make index page
3138
run: echo "<html><head><meta http-equiv='refresh' content='0; URL=ndgrid'></head></html>" > target/doc/index.html

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ cbindgen = "0.29.2"
5050

5151
[package.metadata.docs.rs]
5252
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
53+
rustdoc-args = [ "--html-in-header", "katex-header.html" ]
5354

5455
[lints.clippy]
5556
wildcard_imports = "forbid"

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# ndgrid
22
[![crates.io](https://img.shields.io/crates/v/ndgrid?color=blue)](https://crates.io/crates/ndgrid)
3-
[![docs.rs](https://img.shields.io/docsrs/ndgrid?label=docs.rs)](https://docs.rs/ndgrid/latest/ndgrid/)
43

54
ndgrid is an open-source library written in Rust for n-dimensional grids/meshes.
65

@@ -25,7 +24,6 @@ cargo test
2524
Examples of use can be found in the [examples folder](examples/).
2625

2726
## Getting help
28-
Documentation of the latest release of ndgrid can be found on [docs.rs](https://docs.rs/ndgrid/latest/ndgrid/).
2927
Documentation of the latest development version of ndgrid can be found at [bempp.github.io/ndgrid/ndgrid](https://bempp.github.io/ndgrid/ndgrid).
3028

3129
Errors in the library should be added to the [GitHub issue tracker](https://github.com/bempp/ndgrid/issues).

katex-header.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css" integrity="sha384-WcoG4HRXMzYzfCgiyfrySxx90XSl2rxY5mnVY5TwtWE6KLrArNKn0T/mOgNL0Mmi" crossorigin="anonymous">
2+
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js" integrity="sha384-J+9dG2KMoiR9hqcFao0IBLwxt6zpcyN68IgwzsCSkbreXUjmNVRhPFTssqdSGjwQ" crossorigin="anonymous"></script>
3+
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js" integrity="sha384-hCXGrW6PitJEwbkoStFjeJxv+fSOOQKOPbJxSfM6G5sWZjAyWhXiTIIAmQqnlLlh" crossorigin="anonymous"></script>
4+
<script>
5+
document.addEventListener("DOMContentLoaded", function() {
6+
renderMathInElement(document.body, {
7+
// customised options
8+
// • auto-render specific keys, e.g.:
9+
delimiters: [
10+
{left: '$$', right: '$$', display: true},
11+
{left: '$', right: '$', display: false},
12+
{left: '\\(', right: '\\)', display: false},
13+
{left: '\\[', right: '\\]', display: true}
14+
],
15+
// • rendering keys, e.g.:
16+
throwOnError : false
17+
});
18+
});
19+
</script>

src/geometry/single_element/entity_geometry.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ impl<T: RealScalar, E: FiniteElement> Geometry for SingleElementEntityGeometry<'
6666
fn point_count(&self) -> usize {
6767
self.geometry.cells().shape()[0]
6868
}
69+
6970
fn degree(&self) -> usize {
7071
self.geometry.element().lagrange_superdegree()
7172
}

src/grid/local_grid/single_element/builder.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,28 @@ use rlst::rlst_dynamic_array;
1818
use std::collections::{HashMap, HashSet};
1919

2020
/// Grid builder for a single element grid
21+
///
22+
/// The following gives an example of creating a new grid consisting
23+
/// of a single triangle.
24+
///
25+
/// ```
26+
/// use ndgrid::traits::Builder;
27+
/// use ndgrid::SingleElementGridBuilder;
28+
/// use ndelement::types::ReferenceCellType;
29+
///
30+
/// // The geometric dimension of our space is 3.
31+
/// let gdim = 3;
32+
///
33+
/// // We are building a two dimensional surface triangle grid within a three dimensional space.
34+
/// // Our grid will have three points and one `Triangle` cell of order 1.
35+
/// let mut builder = SingleElementGridBuilder::new_with_capacity(gdim, 3, 1, (ReferenceCellType::Triangle, 1));
36+
/// builder.add_point(0, &[0.0, 0.0, 0.0]);
37+
/// builder.add_point(1, &[1.0, 0.0, 0.0]);
38+
/// builder.add_point(2, &[0.0, 1.0, 0.0]);
39+
/// builder.add_cell(0, &[0, 1, 2]);
40+
///
41+
/// let grid = builder.create_grid();
42+
/// ```
2143
#[derive(Debug)]
2244
pub struct SingleElementGridBuilder<T: RealScalar> {
2345
gdim: usize,

src/lib.rs

Lines changed: 61 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,29 @@
44
//!
55
//! ## Creating a grid with `ndgrid`
66
//!
7-
//! To explain the library we use the following example of a grid consisting of two triangles that together form the unit rectangle.
8-
//! To that effect we introduce the following boundary vertices.
7+
//! To demonstrate the library, we use an example grid consisting of two triangles that together form the unit square.
8+
//! We introduce the following points. As we will make a grid of second oder elements, we include points at the midpoint
9+
//! of each edge as well as at the vertices of the square
910
//! - Point 0: (0, 0)
1011
//! - Point 1: (1, 0)
1112
//! - Point 2: (0, 1)
1213
//! - Point 3: (1, 1)
13-
//!
14-
//! To make matters more interesting we will define a grid of second order elements.
15-
//! This means that each edge of the triangle also has a middle point. The corresponding points are
16-
//! given as follows:
17-
//!
1814
//! - Point 4: (0.5, 0.5)
1915
//! - Point 5: (0.0, 0.5)
2016
//! - Point 6: (0.5, 0.0)
2117
//! - Point 7: (0.5, 1.0)
2218
//! - Point 8: (1.0, 0.5)
2319
//!
24-
//! The order of points for each element is the same as the one on [defelement.org](https://defelement.org).
20+
//! The order of points for each cell follows the point ordering of the
21+
//! [Lagrange element on DefElement](https://defelement.org/elements/lagrange.html).
2522
//! For second order triangles we use
2623
//! [this ordering](https://defelement.org/elements/examples/triangle-lagrange-equispaced-2.html).
24+
//! Following this ordering, the two cells of our example grid are:
2725
//!
28-
//! `ndgrid` does an important distinction between points and topological vertices. The boundary points
29-
//! of the triangle are called vertices and determine the connectivity relationship of this triangle with other
30-
//! triangles. Topologically, the two triangles are defined through the points 0, 1, 2 for the first triangle
31-
//! and 1, 3, 2 for the second triangle. However, the full cell definition is
3226
//! - Cell 1: 0, 1, 2, 4, 5, 6
3327
//! - Cell 2: 1, 3, 2, 7, 4, 8
3428
//!
35-
//! in terms of the points.
36-
//!
37-
//! Let us generate the corresponding data structures.
38-
//!
29+
//! In order to create our grid using ndgrid, we first create a grid builder.
3930
//! ```
4031
//! use ndgrid::traits::Builder;
4132
//! use ndelement::types::ReferenceCellType;
@@ -46,14 +37,21 @@
4637
//! (ReferenceCellType::Triangle, 2),
4738
//! );
4839
//! ```
49-
//! The [SingleElementGridBuilder] is for grids that
50-
//! only use a single element type. The first parameter is the geometric dimension. Here we choose 2,
51-
//! meaning the grid lives in two-dimensionals pace. The next parameter is the number of points, 9 in this case,
52-
//! and the third parameter is the number of cells, which is also 2 here.
53-
//! The element type is [ReferenceCellType::Triangle](ndelement::types::ReferenceCellType::Triangle).
54-
//! The order of the triangles is 2.
55-
//!
56-
//! We now add the definitions of the points and cells.
40+
//!
41+
//! The [SingleElementGridBuilder] is for grids that only use a single element type. The parameters passed when
42+
//! initialising the build are:
43+
//!
44+
//! - The geometric dimension: our example grid lives in two-dimensional space, so we use 2.
45+
//! - The number of points: 9 for our example grid.
46+
//! - The number of cells: 2 for our example grid.
47+
//! - The cell type and element degree: for our example, this is ([ReferenceCellType::Triangle](ndelement::types::ReferenceCellType::Triangle), 2)
48+
//! as our geometry cells are triangles and we use quadratic geometry for each triangle.
49+
//!
50+
//! If we did not know the number of points and cells that we will include in out grid when creating ths builder,
51+
//! we could instead use the function [SingleElementGridBuilder::new] when initialising the grid.
52+
//!
53+
//! Now that we have created a grid builder, we can add the points and cells:
54+
//!
5755
//! ```
5856
//! # use ndgrid::traits::Builder;
5957
//! # use ndelement::types::ReferenceCellType;
@@ -73,8 +71,8 @@
7371
//! builder.add_point(7, &[0.5, 1.0]);
7472
//! builder.add_point(8, &[1.0, 0.5]);
7573
//!
76-
//! builder.add_cell(0, &[0, 1, 2, 4, 5, 6]);
77-
//! builder.add_cell(1, &[1, 3, 2, 7, 4, 8]);
74+
//! builder.add_cell(1, &[0, 1, 2, 4, 5, 6]);
75+
//! builder.add_cell(2, &[1, 3, 2, 7, 4, 8]);
7876
//! ```
7977
//! Finally, we generate the grid.
8078
//! ```
@@ -95,24 +93,34 @@
9593
//! # builder.add_point(6, &[0.5, 0.0]);
9694
//! # builder.add_point(7, &[0.5, 1.0]);
9795
//! # builder.add_point(8, &[1.0, 0.5]);
98-
//!
99-
//! # builder.add_cell(0, &[0, 1, 2, 4, 5, 6]);
100-
//! # builder.add_cell(1, &[1, 3, 2, 7, 4, 8]);
96+
//! #
97+
//! # builder.add_cell(1, &[0, 1, 2, 4, 5, 6]);
98+
//! # builder.add_cell(2, &[1, 3, 2, 7, 4, 8]);
10199
//! let grid = builder.create_grid();
102100
//! ```
101+
//!
103102
//! ## Querying the grid
104103
//!
105-
//! A grid is a hierarchy of entities. The highest dimension entities are the cells. Each cell consists of subentities,
106-
//! which are faces, edges, etc. For each entity there are two types of information, the topology information and the
107-
//! geometry information. The topology describes how entities are connected. The geometry describes how entities related
108-
//! to their associated physical points. Each entity is associated with an `index`. Indices are unique within the class
109-
//! of entities, that is there is a point with index 0 and a cell with index 0 but no two points with index 0. Points and
110-
//! cells also have an associated `id`. `ids` are the indices provided by the user with the `add_point` or `add_cell`
111-
//! methods in the grid builder. These ids will usually be different from the internal indices of entities.
104+
//! A grid is a hierarchy of entities. We follow the standard name conventions for entities of a given topological dimension:
105+
//! 0-, 1-, 2- and 3-dimensional entities and called vertices, edges, faces and volumes (respectively).
106+
//! The highest dimensional entities are called cells. If $d$ the (topological) dimension of the cells,
107+
//! then $d-1$-, $d-2$- and $d-3$-dimensional entities are called facets, ridges and peaks (respectively).
108+
//!
109+
//! For each entity there are two types of information: the topology and the geometry.
110+
//! The topology describes how entities are connected. The geometry describes how entities are positioned in physical space.
111+
//! As the topology is only concerned with the connectivity between entities, it only includes the cell's points that are at
112+
//! the vertices of a cell (eg for the triangle cells in our grid, the topology onle includes the first three points for each cell).
113+
//! In the geometry, all the points that define the cell are stored.
112114
//!
113-
//! The following code extracts all topological vertices for each cell and prints the corresponding physical coordinates.
115+
//! Each entity has an associated `index`. Indices are unique within entities of a given type:
116+
//! there is a vertex with index 0 and a cell with index 0 but there cannot be two vertices with index 0. Points and
117+
//! cells may also have an associated `id`: these are the values provided by the user when using the `add_point` or `add_cell`
118+
//! methods in the grid builder. These ids are not guaranteed to be equal to the indices of the entities.
119+
//!
120+
//! The following code extracts the vertices of each cell and prints their corresponding physical coordinates.
114121
//! ```
115122
//! # use ndgrid::traits::Builder;
123+
//! use ndgrid::traits::{Grid, Entity, Topology, Geometry, Point};
116124
//! # use ndelement::types::ReferenceCellType;
117125
//! # let mut builder = ndgrid::SingleElementGridBuilder::<f64>::new_with_capacity(
118126
//! # 2,
@@ -129,11 +137,11 @@
129137
//! # builder.add_point(6, &[0.5, 0.0]);
130138
//! # builder.add_point(7, &[0.5, 1.0]);
131139
//! # builder.add_point(8, &[1.0, 0.5]);
132-
//!
133-
//! # builder.add_cell(0, &[0, 1, 2, 4, 5, 6]);
134-
//! # builder.add_cell(1, &[1, 3, 2, 7, 4, 8]);
140+
//! #
141+
//! # builder.add_cell(1, &[0, 1, 2, 4, 5, 6]);
142+
//! # builder.add_cell(2, &[1, 3, 2, 7, 4, 8]);
135143
//! # let grid = builder.create_grid();
136-
//! use ndgrid::traits::{Grid, Entity, Topology, Geometry, Point};
144+
//!
137145
//! for cell in grid.entity_iter(ReferenceCellType::Triangle) {
138146
//! for vertex in cell.topology().sub_entity_iter(ReferenceCellType::Point) {
139147
//! let vertex = grid.entity(ReferenceCellType::Point, vertex).unwrap();
@@ -154,26 +162,19 @@
154162
//! }
155163
//! }
156164
//! ```
157-
//! Let us dissect what is going on here. First, we iteratre through the cells of the grid.
158-
//! For this we use the [Grid::entity_iter](crate::traits::Grid::entity_iter) function.
159-
//! For each cell we then access the topology information via [Entity::topology](crate::traits::Entity::topology)
160-
//! and iterate through the point subentities via [Topology::sub_entity_iter](crate::traits::Topology::sub_entity_iter).
161-
//! This gives us the vertices of the triangles. The topology information only considers the points that define the topology.
162-
//! So the middle points on each edge which are necessary for the order of the triangle, are not returned. Also, the iterator
163-
//! returns integer indices of entities. To convert an entity index to an actual entity use the
164-
//! [Grid::entity](crate::traits::Grid::entity) function. We now want to get the actual physical coordinate of a vertex.
165-
//! Since the geometric dimension is 2 we instantiate an array `[f64; 2]` for this. We now call on the vertex the
166-
//! [Entity::geometry](crate::traits::Entity::geometry) function to obtain its geometry information. We then
167-
//! call [Geometry::points](crate::traits::Geometry::points) to get an iterator to all physical points
168-
//! associated with the vertex. Since a vertex only has one associated physical point (namely the vertex itself) we just
169-
//! call `next` once on this iterator to get the actual point. Finally, we call [Point::coords](crate::traits::Point::coords)
170-
//! to get the values of the physical coordinate.
171-
//!
172-
//!
173-
//!
174-
//!
175-
//!
176165
//!
166+
//! This snippets starts by using [Grid::entity_iter](crate::traits::Grid::entity_iter) to iterate through each
167+
//! cell (ie each entity that is a triangle).
168+
//! For each cell, we then access the topology information via [Entity::topology](crate::traits::Entity::topology)
169+
//! and iterate through the vertices (ie the subentities that are points) using [Topology::sub_entity_iter](crate::traits::Topology::sub_entity_iter).
170+
//! This iterators gives us the index of each vertex: to convert an entity index to an entity, we use [Grid::entity](crate::traits::Grid::entity).
171+
//! We now want to get the actual physical coordinate of a vertex.
172+
//! Since the geometric dimension is 2 we instantiate an array `[f64; 2]` for this. We use
173+
//! [Entity::geometry](crate::traits::Entity::geometry) to obtain the geometry for the vertex, then use
174+
//! [Geometry::points](crate::traits::Geometry::points) to get an iterator over the physical points
175+
//! associated with the vertex. Since a vertex has only one associated physical point, we
176+
//! call `next` once on this iterator to get the point. Finally, we call [Point::coords](crate::traits::Point::coords)
177+
//! to get the values of the physical coordinate.
177178
178179
#![cfg_attr(feature = "strict", deny(warnings), deny(unused_crate_dependencies))]
179180
#![warn(missing_docs)]

src/traits/builder.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,6 @@ use std::hash::Hash;
1111
///
1212
/// After instantiation points and cells can be added.
1313
/// To build the actual grid call [Builder::create_grid].
14-
///
15-
/// The following gives an example of creating a new grid consisting
16-
/// of a single triangle.
17-
///
18-
/// ```
19-
/// use ndgrid::traits::Builder;
20-
/// use ndgrid::SingleElementGridBuilder;
21-
/// use ndelement::types::ReferenceCellType;
22-
///
23-
/// // The geometric dimension of our space is 3.
24-
/// let gdim = 3;
25-
///
26-
/// // We are building a two dimensional surface triangle grid within a three dimensional space.
27-
/// // Our grid will have three points and one `Triangle` cell of order 1.
28-
/// let mut builder = SingleElementGridBuilder::new_with_capacity(gdim, 3, 1, (ReferenceCellType::Triangle, 1));
29-
/// builder.add_point(0, &[0.0, 0.0, 0.0]);
30-
/// builder.add_point(1, &[1.0, 0.0, 0.0]);
31-
/// builder.add_point(2, &[0.0, 1.0, 0.0]);
32-
/// builder.add_cell(0, &[0, 1, 2]);
33-
///
34-
/// let grid = builder.create_grid();
35-
/// ```
3614
pub trait Builder {
3715
/// Type used as identifier of different entity types
3816
type EntityDescriptor: Debug + PartialEq + Eq + Clone + Copy + Hash;

0 commit comments

Comments
 (0)