bmi_rust/lib.rs
1#![doc = include_str!("../README.md")]
2#![forbid(unsafe_code)]
3#![deny(missing_docs)]
4
5/// A BMI operation's result, preserving the model's error information.
6pub type BmiResult<T> = Result<T, Box<dyn std::error::Error + Send + Sync>>;
7
8/// The location of a variable's values on its grid.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum Location {
11 /// Grid nodes.
12 Node,
13 /// Grid edges.
14 Edge,
15 /// Grid faces.
16 Face,
17}
18
19/// Grid types defined by BMI 2.0.
20#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub enum GridType {
22 /// A single value with no spatial dimensions.
23 Scalar,
24 /// Disconnected points.
25 Points,
26 /// A one-dimensional unstructured grid.
27 Vector,
28 /// An unstructured grid with explicit connectivity.
29 Unstructured,
30 /// A structured grid of quadrilateral cells.
31 StructuredQuadrilateral,
32 /// A structured grid with independently varying axis spacing.
33 Rectilinear,
34 /// A structured grid with constant spacing along each axis.
35 UniformRectilinear,
36}
37
38/// An owned copy of a variable's numeric values, flattened in model order.
39#[derive(Debug, Clone, PartialEq)]
40pub enum Values {
41 /// Signed 8-bit integers.
42 I8(Vec<i8>),
43 /// Unsigned 8-bit integers.
44 U8(Vec<u8>),
45 /// Signed 16-bit integers.
46 I16(Vec<i16>),
47 /// Unsigned 16-bit integers.
48 U16(Vec<u16>),
49 /// Signed 32-bit integers.
50 I32(Vec<i32>),
51 /// Unsigned 32-bit integers.
52 U32(Vec<u32>),
53 /// Signed 64-bit integers.
54 I64(Vec<i64>),
55 /// Unsigned 64-bit integers.
56 U64(Vec<u64>),
57 /// 32-bit floating-point values.
58 F32(Vec<f32>),
59 /// 64-bit floating-point values.
60 F64(Vec<f64>),
61}
62
63/// Borrowed numeric values used for direct reads and setter inputs.
64#[derive(Debug, Clone, Copy, PartialEq)]
65pub enum RefValues<'a> {
66 /// Signed 8-bit integers.
67 I8(&'a [i8]),
68 /// Unsigned 8-bit integers.
69 U8(&'a [u8]),
70 /// Signed 16-bit integers.
71 I16(&'a [i16]),
72 /// Unsigned 16-bit integers.
73 U16(&'a [u16]),
74 /// Signed 32-bit integers.
75 I32(&'a [i32]),
76 /// Unsigned 32-bit integers.
77 U32(&'a [u32]),
78 /// Signed 64-bit integers.
79 I64(&'a [i64]),
80 /// Unsigned 64-bit integers.
81 U64(&'a [u64]),
82 /// 32-bit floating-point values.
83 F32(&'a [f32]),
84 /// 64-bit floating-point values.
85 F64(&'a [f64]),
86}
87
88/// The [CSDMS Basic Model Interface 2.0](https://bmi.csdms.io/en/stable/).
89///
90/// Initialize a model before querying or updating it, and finalize it after use.
91/// Variable names follow the model's advertised input and output names. Grid
92/// identifiers are model-defined; indices and sizes use Rust's `usize`.
93///
94/// All methods are fallible and required. Implementations should return errors
95/// for invalid names, grid identifiers, indices, types, buffer lengths, lifecycle
96/// states, and operations unsupported by their grid or storage representation.
97/// Setters must validate their inputs before modifying model storage.
98///
99/// This trait is dyn-compatible, so coupling code can use `Box<dyn Bmi>`.
100pub trait Bmi {
101 /// Load configuration from `config_file` and allocate model resources.
102 /// An empty path requests the model's default configuration, if supported.
103 fn initialize(&mut self, config_file: &str) -> BmiResult<()>;
104 /// Advance the model by one time step.
105 fn update(&mut self) -> BmiResult<()>;
106 /// Advance to `time`, expressed in the model's time units.
107 fn update_until(&mut self, time: f64) -> BmiResult<()>;
108 /// Release model resources and finish any pending output.
109 fn finalize(&mut self) -> BmiResult<()>;
110
111 /// Return the model's human-readable component name.
112 fn get_component_name(&self) -> BmiResult<String>;
113 /// Return the number of input variables.
114 fn get_input_item_count(&self) -> BmiResult<usize>;
115 /// Return the number of output variables.
116 fn get_output_item_count(&self) -> BmiResult<usize>;
117 /// Return the names of variables that can be set.
118 fn get_input_var_names(&self) -> BmiResult<Vec<String>>;
119 /// Return the names of variables that can be read.
120 fn get_output_var_names(&self) -> BmiResult<Vec<String>>;
121
122 /// Return the grid identifier associated with a variable.
123 fn get_var_grid(&self, name: &str) -> BmiResult<i32>;
124 /// Return the variable's native type name (for example, `float64`).
125 fn get_var_type(&self, name: &str) -> BmiResult<String>;
126 /// Return the variable's units, preferably using UDUNITS conventions.
127 fn get_var_units(&self, name: &str) -> BmiResult<String>;
128 /// Return the size of one variable element in bytes.
129 fn get_var_itemsize(&self, name: &str) -> BmiResult<usize>;
130 /// Return the total size of a variable's values in bytes.
131 fn get_var_nbytes(&self, name: &str) -> BmiResult<usize>;
132 /// Return whether the variable is defined on nodes, edges, or faces.
133 fn get_var_location(&self, name: &str) -> BmiResult<Location>;
134
135 /// Return the current simulation time.
136 fn get_current_time(&self) -> BmiResult<f64>;
137 /// Return the simulation's start time.
138 fn get_start_time(&self) -> BmiResult<f64>;
139 /// Return the simulation's end time.
140 fn get_end_time(&self) -> BmiResult<f64>;
141 /// Return the units used by every time query and `update_until`.
142 fn get_time_units(&self) -> BmiResult<String>;
143 /// Return the model's current time-step duration.
144 fn get_time_step(&self) -> BmiResult<f64>;
145
146 /// Return an owned copy of all values, preserving their numeric type.
147 fn get_value(&self, name: &str) -> BmiResult<Values>;
148 /// Borrow the model's storage without copying it.
149 ///
150 /// The slice cannot outlive the model borrow. Rust prevents mutable calls,
151 /// including `update`, `set_value`, and `finalize`, while it is still in use.
152 /// Changes must go through the setters; no mutable raw pointer is exposed.
153 fn get_value_ptr(&self, name: &str) -> BmiResult<RefValues<'_>>;
154 /// Copy values at zero-based flattened indices, in the requested order.
155 /// Repeated indices repeat values; an empty index slice returns no values.
156 fn get_value_at_indices(&self, name: &str, indices: &[usize]) -> BmiResult<Values>;
157 /// Copy `src` into a variable. Its type and length must match the variable.
158 fn set_value(&mut self, name: &str, src: RefValues<'_>) -> BmiResult<()>;
159 /// Copy values into zero-based flattened indices.
160 /// `src` must match the variable's type and have one value per index.
161 fn set_value_at_indices(
162 &mut self,
163 name: &str,
164 indices: &[usize],
165 src: RefValues<'_>,
166 ) -> BmiResult<()>;
167
168 /// Return the number of spatial dimensions.
169 fn get_grid_rank(&self, grid: i32) -> BmiResult<usize>;
170 /// Return the total number of grid nodes.
171 fn get_grid_size(&self, grid: i32) -> BmiResult<usize>;
172 /// Return the grid's topology and geometry category.
173 fn get_grid_type(&self, grid: i32) -> BmiResult<GridType>;
174 /// Return the node count along each axis, ordered slowest to fastest (z, y, x).
175 /// The returned length equals the grid rank.
176 fn get_grid_shape(&self, grid: i32) -> BmiResult<Vec<usize>>;
177 /// Return uniform axis spacing, ordered as `get_grid_shape`.
178 fn get_grid_spacing(&self, grid: i32) -> BmiResult<Vec<f64>>;
179 /// Return the grid origin, ordered as `get_grid_shape`.
180 fn get_grid_origin(&self, grid: i32) -> BmiResult<Vec<f64>>;
181 /// Return x coordinates: axis coordinates for rectilinear grids, otherwise per node.
182 fn get_grid_x(&self, grid: i32) -> BmiResult<Vec<f64>>;
183 /// Return y coordinates: axis coordinates for rectilinear grids, otherwise per node.
184 fn get_grid_y(&self, grid: i32) -> BmiResult<Vec<f64>>;
185 /// Return z coordinates: axis coordinates for rectilinear grids, otherwise per node.
186 fn get_grid_z(&self, grid: i32) -> BmiResult<Vec<f64>>;
187 /// Return the number of nodes in an unstructured grid.
188 fn get_grid_node_count(&self, grid: i32) -> BmiResult<usize>;
189 /// Return the number of edges in an unstructured grid.
190 fn get_grid_edge_count(&self, grid: i32) -> BmiResult<usize>;
191 /// Return the number of faces in an unstructured grid.
192 fn get_grid_face_count(&self, grid: i32) -> BmiResult<usize>;
193 /// Return flattened node pairs for edges, with two indices per edge.
194 fn get_grid_edge_nodes(&self, grid: i32) -> BmiResult<Vec<usize>>;
195 /// Return flattened edge indices for faces, grouped in face order.
196 fn get_grid_face_edges(&self, grid: i32) -> BmiResult<Vec<usize>>;
197 /// Return flattened node indices for faces, grouped in face order.
198 fn get_grid_face_nodes(&self, grid: i32) -> BmiResult<Vec<usize>>;
199 /// Return the node count per face, delimiting the flattened face connectivity arrays.
200 fn get_grid_nodes_per_face(&self, grid: i32) -> BmiResult<Vec<usize>>;
201}