Repository navigation
Add crate documentation #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,3 +1,23 @@ | ||||||
| //! The preCICE rust bindings. | ||||||
| //! | ||||||
| //! These are the official rust bindings for the [preCICE coupling library](https://precice.org). | ||||||
| //! | ||||||
| //! The methods of the [Participant] map directly to their C++ counterparts. | ||||||
| //! Therefore the documentation of this crate is kept relatively minimal. | ||||||
|
Comment on lines
+5
to
+6
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not necessarily a documentation issue but: Similar issue as with the Fortran module: how do we ensure that all the methods in this repository still exist or have the right signatures? Triggered by a similar question: "how do we ensure consistency in the documentation"? Since this is not Doxygen, we cannot do |
||||||
| //! | ||||||
| //! Have a deeper look at the official documentation: | ||||||
| //! | ||||||
| //! - The [official documentation](https://precice.org/docs.html) explains what preCICE is and how | ||||||
| //! to use it. | ||||||
| //! - The [API documentation](https://precice.org/dev-docs-sourcedocs.html) explains the API | ||||||
| //! conditions in detail. | ||||||
| //! | ||||||
| //! # Example applications | ||||||
| //! | ||||||
| //! - The crate contains a [solverdummy](https://github.com/precice/rust-bindings/tree/main/examples) as example. | ||||||
| //! - The tutorials contain a rust version of both participants for the [1D elastic-tube tutorial](https://precice.org/tutorials-elastic-tube-1d.html). | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this list could get outdated quickly, I would rather point either to the Tutorials overview, or to such a URL: https://github.com/search?q=repo%3Aprecice%2Ftutorials%20Cargo.toml&type=code
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a good idea!
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a good idea! |
||||||
|
|
||||||
| #[warn(missing_docs)] | ||||||
| #[cxx::bridge(namespace = "precice::rust")] | ||||||
| mod ffi { | ||||||
| unsafe extern "C++" { | ||||||
|
|
@@ -177,70 +197,125 @@ pub struct Participant { | |||||
| internal: cxx::UniquePtr<ffi::Participant>, | ||||||
| } | ||||||
|
|
||||||
| /// Type of vertex identifiers. | ||||||
| /// | ||||||
| /// These are returned either by | ||||||
| /// - manually setting vertices from coordinates using [Participant::set_mesh_vertex] and [Participant::set_mesh_vertices], or | ||||||
| /// - using direct api-access with [Participant::get_mesh_vertex_ids_and_coordinates]. | ||||||
| pub type VertexID = i32; | ||||||
|
|
||||||
| /// Type of thrown errors from preCICE | ||||||
| pub type Error = cxx::Exception; | ||||||
|
|
||||||
| impl Participant { | ||||||
| pub fn new(participant: &str, config: &str, rank: i32, size: i32) -> Result<Self, Error> { | ||||||
| // Creates a new preCICE participant. | ||||||
| // | ||||||
| // The participant is named `participant` and is descried in the configuration file located at `config`. | ||||||
| // | ||||||
| // The communicator size and rank match the MPI terminology. | ||||||
| // Participants running in serial or not using MPI pass `rank = 0` and `size = 1`. | ||||||
| pub fn new( | ||||||
| participant: &str, | ||||||
| config: &str, | ||||||
| rank: i32, | ||||||
| size: i32, | ||||||
| ) -> Result<Participant, Error> { | ||||||
| Ok(Participant { | ||||||
| internal: ffi::create_participant(participant, config, rank, size)?, | ||||||
| }) | ||||||
| } | ||||||
|
|
||||||
| // Steering Methods | ||||||
|
|
||||||
| /// Initializes the participant. | ||||||
| pub fn initialize(&mut self) -> Result<(), Error> { | ||||||
| self.internal.pin_mut().initialize() | ||||||
| } | ||||||
|
|
||||||
| /// Advances the participant in time by the time-step-size `dt`. | ||||||
| pub fn advance(&mut self, dt: f64) -> Result<(), Error> { | ||||||
| self.internal.pin_mut().advance(dt) | ||||||
| } | ||||||
|
|
||||||
| /// Explicitly finalizes the participant, which is not necessary for most use-cases. | ||||||
| pub fn finalize(&mut self) -> Result<(), Error> { | ||||||
| self.internal.pin_mut().finalize() | ||||||
| } | ||||||
|
|
||||||
| // Implicit coupling | ||||||
|
|
||||||
| /// Checks if the solver needs to read an iteration checkpoint. | ||||||
| pub fn requires_reading_checkpoint(&mut self) -> Result<bool, Error> { | ||||||
| self.internal.pin_mut().requires_reading_checkpoint() | ||||||
| } | ||||||
|
|
||||||
| /// Checks if the solver needs to write an iteration checkpoint. | ||||||
| pub fn requires_writing_checkpoint(&mut self) -> Result<bool, Error> { | ||||||
| self.internal.pin_mut().requires_writing_checkpoint() | ||||||
| } | ||||||
|
|
||||||
| // Status Queries | ||||||
|
|
||||||
| /// Returns the spatial dimensions of a mesh. | ||||||
| pub fn get_mesh_dimensions(&self, mesh_name: &str) -> Result<i32, Error> { | ||||||
| self.internal.get_mesh_dimensions(mesh_name) | ||||||
| } | ||||||
|
|
||||||
| /// Returns the spatial dimensions of a data defined on a mesh. | ||||||
| pub fn get_data_dimensions(&self, mesh_name: &str, data_name: &str) -> Result<i32, Error> { | ||||||
| self.internal.get_data_dimensions(mesh_name, data_name) | ||||||
| } | ||||||
|
|
||||||
| /// Checks is the coupling is still ongoing . | ||||||
| pub fn is_coupling_ongoing(&self) -> Result<bool, Error> { | ||||||
| self.internal.is_coupling_ongoing() | ||||||
| } | ||||||
|
|
||||||
| /// Checks if the previous step completed the time window. | ||||||
| pub fn is_time_window_complete(&self) -> Result<bool, Error> { | ||||||
| self.internal.is_time_window_complete() | ||||||
| } | ||||||
|
|
||||||
| /// Returns the maximum time-step-size allowed by a solver at the moment of calling. | ||||||
| /// | ||||||
| /// Note that this can return [f64::INFINITY] if the participant prescribes the time-window-size | ||||||
| /// in a serial coupling scheme. | ||||||
| pub fn get_max_time_step_size(&self) -> Result<f64, Error> { | ||||||
| self.internal.get_max_time_step_size() | ||||||
| } | ||||||
|
|
||||||
| // Mesh Access | ||||||
|
|
||||||
| /// Check if the mesh makes use of mesh connectivity. | ||||||
| pub fn requires_mesh_connectivity_for(&self, mesh_name: &str) -> Result<bool, Error> { | ||||||
| self.internal.requires_mesh_connectivity_for(mesh_name) | ||||||
| } | ||||||
|
|
||||||
| /// Deletes all vertices of a mesh. | ||||||
| pub fn reset_mesh(&mut self, mesh_name: &str) -> Result<(), Error> { | ||||||
| self.internal.pin_mut().reset_mesh(mesh_name) | ||||||
| } | ||||||
|
|
||||||
| /// Returns the amount of vertices of a mesh. | ||||||
| /// | ||||||
| /// For a provided mesh, returns the amount of vertices. | ||||||
| /// | ||||||
| /// For a received mesh using API-access, returns the amount of vertices received. | ||||||
| /// This is necessary to allocate output vectors for [Participant::get_mesh_vertex_ids_and_coordinates] | ||||||
| pub fn get_mesh_vertex_size(&self, mesh_name: &str) -> Result<i32, Error> { | ||||||
| self.internal.get_mesh_vertex_size(mesh_name) | ||||||
| } | ||||||
|
|
||||||
| /// Add a vertex of given position to a mesh and returns a [VertexID]. | ||||||
| pub fn set_mesh_vertex( | ||||||
| &mut self, | ||||||
| mesh_name: &str, | ||||||
| position: &[f64], | ||||||
| ) -> Result<VertexID, Error> { | ||||||
| self.internal.pin_mut().set_mesh_vertex(mesh_name, position) | ||||||
| } | ||||||
| pub fn get_mesh_vertex_size(&self, mesh_name: &str) -> Result<i32, Error> { | ||||||
| self.internal.get_mesh_vertex_size(mesh_name) | ||||||
| } | ||||||
|
|
||||||
| /// Add multiple vertices of given positions to a mesh and writes their [VertexID]s to `ids` . | ||||||
| pub fn set_mesh_vertices( | ||||||
| &mut self, | ||||||
| mesh_name: &str, | ||||||
|
|
@@ -251,6 +326,8 @@ impl Participant { | |||||
| .pin_mut() | ||||||
| .set_mesh_vertices(mesh_name, positions, ids) | ||||||
| } | ||||||
|
|
||||||
| /// Defines an edge between two vertices. | ||||||
| pub fn set_mesh_edge( | ||||||
| &mut self, | ||||||
| mesh_name: &str, | ||||||
|
|
@@ -261,9 +338,13 @@ impl Participant { | |||||
| .pin_mut() | ||||||
| .set_mesh_edge(mesh_name, first_vertex_id, second_vertex_id) | ||||||
| } | ||||||
|
|
||||||
| /// Defines edges between multiple vertex pairs. | ||||||
| pub fn set_mesh_edges(&mut self, mesh_name: &str, vertices: &[VertexID]) -> Result<(), Error> { | ||||||
| self.internal.pin_mut().set_mesh_edges(mesh_name, vertices) | ||||||
| } | ||||||
|
|
||||||
| /// Defines a triangle between three vertices. | ||||||
| pub fn set_mesh_triangle( | ||||||
| &mut self, | ||||||
| mesh_name: &str, | ||||||
|
|
@@ -278,6 +359,8 @@ impl Participant { | |||||
| third_vertex_id, | ||||||
| ) | ||||||
| } | ||||||
|
|
||||||
| /// Defines triangles between vertex triples. | ||||||
| pub fn set_mesh_triangles( | ||||||
| &mut self, | ||||||
| mesh_name: &str, | ||||||
|
|
@@ -287,6 +370,8 @@ impl Participant { | |||||
| .pin_mut() | ||||||
| .set_mesh_triangles(mesh_name, vertices) | ||||||
| } | ||||||
|
|
||||||
| /// Defines a planar quad between four vertices. | ||||||
| pub fn set_mesh_quad( | ||||||
| &mut self, | ||||||
| mesh_name: &str, | ||||||
|
|
@@ -303,9 +388,13 @@ impl Participant { | |||||
| fourth_vertex_id, | ||||||
| ) | ||||||
| } | ||||||
|
|
||||||
| /// Defines multiple planar quads between vertex quadruples. | ||||||
| pub fn set_mesh_quads(&mut self, mesh_name: &str, vertices: &[VertexID]) -> Result<(), Error> { | ||||||
| self.internal.pin_mut().set_mesh_quads(mesh_name, vertices) | ||||||
| } | ||||||
|
|
||||||
| /// Defines a tetrahedron between four vertices. | ||||||
| pub fn set_mesh_tetrahedron( | ||||||
| &mut self, | ||||||
| mesh_name: &str, | ||||||
|
|
@@ -322,6 +411,8 @@ impl Participant { | |||||
| fourth_vertex_id, | ||||||
| ) | ||||||
| } | ||||||
|
|
||||||
| /// Defines multiple tetrahedra between vertex quadruples. | ||||||
| pub fn set_mesh_tetrahedra( | ||||||
| &mut self, | ||||||
| mesh_name: &str, | ||||||
|
|
@@ -334,10 +425,13 @@ impl Participant { | |||||
|
|
||||||
| // Data Access | ||||||
|
|
||||||
| /// Checks if this participant needs to provide initial data using [Participant::write_data] | ||||||
| /// before calling [Participant::initialize]. | ||||||
| pub fn requires_initial_data(&mut self) -> Result<bool, Error> { | ||||||
| self.internal.pin_mut().requires_initial_data() | ||||||
| } | ||||||
|
|
||||||
| /// Writes data to a mesh for given [VertexID]s. | ||||||
| pub fn write_data( | ||||||
| &mut self, | ||||||
| mesh_name: &str, | ||||||
|
|
@@ -349,6 +443,8 @@ impl Participant { | |||||
| .pin_mut() | ||||||
| .write_data(mesh_name, data_name, vertices, values) | ||||||
| } | ||||||
|
|
||||||
| /// Reads data values from a mesh for given [VertexID]s at a given `relative_read_dt`. | ||||||
| pub fn read_data( | ||||||
| &self, | ||||||
| mesh_name: &str, | ||||||
|
|
@@ -363,18 +459,21 @@ impl Participant { | |||||
|
|
||||||
| // User Profiling | ||||||
|
|
||||||
| /// Starts a new user-defined profiling section. | ||||||
| pub fn start_profiling_section(&mut self, section_name: &str) -> Result<(), Error> { | ||||||
| self.internal | ||||||
| .pin_mut() | ||||||
| .start_profiling_section(section_name) | ||||||
| } | ||||||
|
|
||||||
| /// Stops the last user-defined profiling section. | ||||||
| pub fn stop_last_profiling_section(&mut self) -> Result<(), Error> { | ||||||
| self.internal.pin_mut().stop_last_profiling_section() | ||||||
| } | ||||||
|
|
||||||
| // Direct Access | ||||||
|
|
||||||
| /// Defines a region of interest on a received mesh. | ||||||
| pub fn set_mesh_access_region( | ||||||
| &mut self, | ||||||
| mesh_name: &str, | ||||||
|
|
@@ -384,6 +483,11 @@ impl Participant { | |||||
| .pin_mut() | ||||||
| .set_mesh_access_region(mesh_name, bounding_box) | ||||||
| } | ||||||
|
|
||||||
| /// Reads [VertexID]s and coordinates of a received mesh. | ||||||
| /// | ||||||
| /// Use [Participant::get_mesh_vertex_size] and [Participant::get_mesh_dimensions] to | ||||||
| /// preallocate the output storage. | ||||||
| pub fn get_mesh_vertex_ids_and_coordinates( | ||||||
| &self, | ||||||
| mesh_name: &str, | ||||||
|
|
@@ -396,6 +500,7 @@ impl Participant { | |||||
|
|
||||||
| // experimental: Gradient Data | ||||||
|
|
||||||
| /// Checks if the given data set requires gradient data. | ||||||
| pub fn requires_gradient_data_for( | ||||||
| &self, | ||||||
| mesh_name: &str, | ||||||
|
|
@@ -404,6 +509,15 @@ impl Participant { | |||||
| self.internal | ||||||
| .requires_gradient_data_for(mesh_name, data_name) | ||||||
| } | ||||||
|
|
||||||
| /// Writes vector gradient data to a mesh. | ||||||
| /// | ||||||
| /// The used format for `gradients` follows this pattern: | ||||||
| /// | ||||||
| /// | Spatial Dimensions | Scalar Data | Vectorial Data | | ||||||
| /// | --- | --- | --- | | ||||||
| /// | **2D** | s dx, s dy | x dx, y dx, x dy, y dy | | ||||||
| /// | **3D** | s dy, s dy, s dz | x dx, y dx, z dx, x dy, y dy, z dy, x dz, y dz, z dz | | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
| pub fn write_gradient_data( | ||||||
| &mut self, | ||||||
| mesh_name: &str, | ||||||
|
|
@@ -418,6 +532,9 @@ impl Participant { | |||||
|
|
||||||
| // experimental: JIT mapping | ||||||
|
|
||||||
| /// Reads data values from a mesh using a just-in-time data mapping. | ||||||
| /// | ||||||
| /// Values correspond to a given point in time relative to the beginning of the current time-step. | ||||||
| pub fn write_and_map_data( | ||||||
| &mut self, | ||||||
| mesh_name: &str, | ||||||
|
|
@@ -430,6 +547,7 @@ impl Participant { | |||||
| .write_and_map_data(mesh_name, data_name, coordinates, values) | ||||||
| } | ||||||
|
|
||||||
| /// Writes data values to a mesh using a just-in-time mapping (experimental). | ||||||
| pub fn map_and_read_data( | ||||||
| &self, | ||||||
| mesh_name: &str, | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could not build this on my system. Since the default Rust on my system (1.75) was too old, I installed the latest available (1.89), but I still get an issue:
Would it be a good idea to add the building step to the CI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CI yes. Especially as it doesn't require a precice installation