1pub mod magic;
9pub mod sampling;
10
11pub use magic::{magic, magic_with, MagicOutput, MagicParams, MagicSelection};
12pub use sampling::{AliasTable, MeshSourceSampler, Mode, SampledVoxel};
13
14#[derive(Debug, Clone, PartialEq)]
16pub enum Error {
17 EmptyTally,
19 LengthMismatch { expected: usize, got: usize },
21 ZeroMaxFlux { energy_group: usize },
25 EmptyPdf,
27 NegativePdf { index: usize, value: f64 },
29 NonFinitePdf { index: usize },
31 ZeroSumPdf,
33 NegativeTally { index: usize, value: f64 },
35 NonFiniteTally { field: &'static str, index: usize },
37}
38
39impl std::fmt::Display for Error {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 match self {
42 Error::EmptyTally => write!(f, "tally contains no volume elements"),
43 Error::LengthMismatch { expected, got } => {
44 write!(f, "length mismatch: expected {expected}, got {got}")
45 }
46 Error::ZeroMaxFlux { energy_group } => write!(
47 f,
48 "energy group {energy_group} has no positive flux; \
49 weight-window normalization would divide by zero"
50 ),
51 Error::EmptyPdf => write!(f, "pdf must contain at least one value"),
52 Error::NegativePdf { index, value } => {
53 write!(f, "pdf[{index}] = {value} is negative")
54 }
55 Error::NonFinitePdf { index } => write!(f, "pdf[{index}] is not finite"),
56 Error::ZeroSumPdf => write!(f, "pdf sums to zero; cannot normalize"),
57 Error::NegativeTally { index, value } => write!(
58 f,
59 "tally/density value at index {index} = {value} is negative"
60 ),
61 Error::NonFiniteTally { field, index } => {
62 write!(f, "{field}[{index}] is not finite")
63 }
64 }
65 }
66}
67
68impl std::error::Error for Error {}
69
70#[cfg(test)]
71mod tests {
72 use super::Error;
73
74 #[test]
75 fn error_display_covers_all_variants() {
76 let cases: Vec<(Error, &str)> = vec![
77 (Error::EmptyTally, "no volume elements"),
78 (
79 Error::LengthMismatch {
80 expected: 3,
81 got: 5,
82 },
83 "expected 3, got 5",
84 ),
85 (Error::ZeroMaxFlux { energy_group: 2 }, "energy group 2"),
86 (Error::EmptyPdf, "at least one value"),
87 (
88 Error::NegativePdf {
89 index: 1,
90 value: -0.5,
91 },
92 "pdf[1]",
93 ),
94 (Error::NonFinitePdf { index: 0 }, "pdf[0]"),
95 (Error::ZeroSumPdf, "sums to zero"),
96 (
97 Error::NegativeTally {
98 index: 4,
99 value: -1.0,
100 },
101 "index 4",
102 ),
103 (
104 Error::NonFiniteTally {
105 field: "flux",
106 index: 7,
107 },
108 "flux[7]",
109 ),
110 ];
111 for (err, needle) in cases {
112 assert!(
113 format!("{err}").contains(needle),
114 "display of {err:?} should contain {needle:?}"
115 );
116 let _: &dyn std::error::Error = &err;
118 }
119 }
120}