outram_foam_basic_lib/mesh/error.rs
1// SPDX-License-Identifier: GPL-3.0-only
2// Copyright (C) 2026 OUTRAM PARK contributors
3
4/// Errors produced by the mesh layer (mesh construction and validation).
5#[derive(Debug, Clone, PartialEq)]
6pub enum MeshError {
7 /// An array field in the mesh has the wrong length.
8 ///
9 /// For example, `owner` must have length `n_faces`; `neighbour` must have
10 /// length `n_internal_faces`; `cell_volumes` must have length `n_cells`.
11 ArrayLengthMismatch {
12 /// Name of the offending array (e.g. `"owner"`, `"cell_volumes"`).
13 array: &'static str,
14 expected: usize,
15 got: usize,
16 },
17
18 /// A boundary patch does not start immediately after the previous one,
19 /// leaving a gap or overlap in face coverage.
20 PatchStartMismatch {
21 /// Name of the offending patch.
22 name: String,
23 expected: usize,
24 got: usize,
25 },
26
27 /// The sum of all patch sizes does not equal the number of boundary faces.
28 PatchCoverageMismatch {
29 /// Total face count covered by all patches.
30 covered: usize,
31 /// Total face count in the mesh.
32 n_faces: usize,
33 },
34
35 /// `number_of_cells` was zero or negative when building a 1-D mesh.
36 NonPositiveCellCount { got: i64 },
37
38 /// A [`PatchKind::Cyclic`](crate::mesh::PatchKind::Cyclic) patch pair is
39 /// inconsistent — e.g. the partner index is out of range, the partner does
40 /// not name this patch back, or the two halves have different face counts.
41 CyclicPairMismatch {
42 /// Name of the offending cyclic patch.
43 name: String,
44 /// Why the pair is invalid.
45 reason: &'static str,
46 },
47
48 /// A [`PatchKind::CyclicAmi`](crate::mesh::PatchKind::CyclicAmi)
49 /// (non-conformal periodic) coupling is inconsistent — e.g. a target/source
50 /// cell or face index is out of range, or a target face has no overlapping
51 /// source faces.
52 AmiCouplingInvalid {
53 /// Global face index of the offending AMI target face.
54 target_face: usize,
55 /// Why the coupling is invalid.
56 reason: &'static str,
57 },
58}
59
60impl std::fmt::Display for MeshError {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 match self {
63 MeshError::ArrayLengthMismatch {
64 array,
65 expected,
66 got,
67 } => write!(
68 f,
69 "mesh array '{array}': expected length {expected}, got {got}"
70 ),
71 MeshError::PatchStartMismatch {
72 name,
73 expected,
74 got,
75 } => write!(
76 f,
77 "patch '{name}': expected to start at face {expected}, starts at {got}"
78 ),
79 MeshError::PatchCoverageMismatch { covered, n_faces } => write!(
80 f,
81 "boundary patches cover {covered} faces but n_faces = {n_faces}"
82 ),
83 MeshError::NonPositiveCellCount { got } => {
84 write!(f, "number_of_cells must be ≥ 1, got {got}")
85 }
86 MeshError::CyclicPairMismatch { name, reason } => {
87 write!(f, "cyclic patch '{name}': {reason}")
88 }
89 MeshError::AmiCouplingInvalid {
90 target_face,
91 reason,
92 } => {
93 write!(f, "AMI coupling at target face {target_face}: {reason}")
94 }
95 }
96 }
97}
98
99impl std::error::Error for MeshError {}