Skip to main content

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}