1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//! # Module `mesh`
//!
//! Spatial mesh abstraction — INV-1 invariant (DD-007, DD-019, issue #31).
//!
//! ## Core principle (INV-1)
//!
//! No public engine API exposes `dx`, `nx` or raw indices as first-class spatial
//! parameters. All spatial references go through the `Mesh` trait. This guarantees
//! forward compatibility with FEM unstructured meshes at J7 — zero breaking change
//! on existing code when `unstructured/` is added.
//!
//! ## Module hierarchy (DD-019)
//!
//! ```text
//! src/mesh/
//! ├── mod.rs — Mesh trait + public re-exports
//! ├── structured/
//! │ └── mod.rs — UniformGrid1D (J1); UniformGrid2D (J4b+)
//! └── unstructured/ — RESERVED J7 (UnstructuredMesh2D, TetrahedralMesh3D)
//! ```
//!
//! ## Implementations
//!
//! | Type | Family | Description | Milestone |
//! |---|---|---|---|
//! | [`UniformGrid1D`] | structured | 1D uniform grid, FD/FV | J1 — v0.1.0 |
//! | `UnstructuredMesh2D` | unstructured | 2D triangular mesh, FEM | J7 — v2.0.0 |
//! | `TetrahedralMesh3D` | unstructured | 3D tetrahedral mesh, FEM | J7 — v2.0.0 |
// unstructured/ — RESERVED J7
// pub mod unstructured;
// ── Public re-exports ─────────────────────────────────────────────────────────
pub use UniformGrid1D;
// ── Mesh trait ────────────────────────────────────────────────────────────────
/// Abstract spatial mesh — INV-1 invariant.
///
/// All spatial information consumed by the engine passes through this trait.
/// No implementation detail (`dx`, `nx`, node table) leaks into the public API.
///
/// # Object safety
///
/// This trait is object-safe: it can be used as `Box<dyn Mesh>` and `&dyn Mesh`.
/// Required for INV-4 (plugin-safe API, J7).
///
/// # Implementing `Mesh`
///
/// A minimal implementation for a 1D uniform grid:
///
/// ```rust
/// use oxiflow::mesh::Mesh;
///
/// struct MyGrid { n: usize, dx: f64 }
///
/// impl Mesh for MyGrid {
/// fn n_dof(&self) -> usize { self.n }
/// fn coordinates(&self, i: usize) -> &[f64] {
/// // In practice, return a slice into a pre-computed node table.
/// // This example uses a workaround for illustration only.
/// std::slice::from_ref(Box::leak(Box::new(i as f64 * self.dx)))
/// }
/// fn spatial_dimension(&self) -> usize { 1 }
/// fn characteristic_length(&self) -> f64 { self.dx }
/// }
/// ```
///
/// # INV-1 compliance
///
/// Implementations must **not** expose `dx`, `nx` or raw indices in any public
/// method beyond those defined here. Spatial parameters are internal details.