1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
//! The `fmi` crate implements a Rust interface to FMUs (Functional Mockup Units) that follow FMI //! Standard. This version of the library supports FMI2.0. See http://www.fmi-standard.org/ //! //! # Examples //! //! ``` //! let import = fmi::Import::new(std::path::Path::new("data/Modelica_Blocks_Sources_Sine.fmu")).unwrap(); //! let instance1 = fmi::InstanceME::new(&import, "inst1", false, true).unwrap(); //! ``` #[macro_use] extern crate derive_more; pub mod fmi; pub mod import; pub mod instance; pub mod logger; pub mod model_descr; pub mod variable; // Re-exports pub use self::fmi::FmiApi; pub use self::import::Import; pub use self::instance::{CoSimulation, Common, InstanceCS, InstanceME, ModelExchange}; pub use self::variable::Var; use failure::{Error, Fail}; /// Crate-wide Result type pub type Result<T> = std::result::Result<T, failure::Error>; #[derive(Debug, Fail)] pub enum FmiError { #[fail(display = "error instantiating import")] Instantiation, #[fail(display = "Invalid fmi2Status {}", status)] InvalidStatus { status: u32 }, /// For ME: It is recommended to perform a smaller step size and evaluate the model equations /// again, for example because an iterative solver in the model did not converge or because a /// function is outside of its domain (for example sqrt(<negative number>)). If this is not /// possible, the simulation has to be terminated. /// /// For CS: fmi2Discard is returned also if the slave is not able to return the required status /// information. The master has to decide if the simulation run can be continued. #[fail(display = "fmi2Discard")] FmiStatusDiscard, /// The FMU encountered an error. /// The simulation cannot be continued with this FMU instance. /// If one of the functions returns fmi2Error, it can be tried to restart the simulation from /// a formerly stored FMU state by calling fmi2SetFMUstate. This can be done if the capability /// flag canGetAndSetFMUstate is true and fmu2GetFMUstate was called before in non-erroneous /// state. If not, the simulation cannot be continued and fmi2FreeInstance or fmi2Reset must /// be called afterwards. #[fail(display = "fmi2Error")] FmiStatusError, /// The model computations are irreparably corrupted for all FMU instances. /// [For example, due to a run-time exception such as access violation or integer division by /// zero during the execution of an fmi function]. /// It is not possible to call any other function for any of the FMU instances. #[fail(display = "fmi2Fatal")] FmiStatusFatal, #[fail(display = "Unknown variable: {}", name)] UnknownVariable { name: String }, #[fail(display = "unknown toolchain version: {}", version)] UnknownToolchainVersion { version: String }, } /// Helper function to handle returned fmi2Status values fn handle_status_u32(status: u32) -> Result<()> { use num_traits::cast::FromPrimitive; if let Some(status) = fmi::Status::from_u32(status) { match status { fmi::Status::OK => Ok(()), fmi::Status::Warning => Ok(()), fmi::Status::Discard => Err(FmiError::FmiStatusDiscard), fmi::Status::Error => Err(FmiError::FmiStatusError), fmi::Status::Fatal => Err(FmiError::FmiStatusFatal), fmi::Status::Pending => Ok(()), } .map_err(Error::from) } else { Err(FmiError::InvalidStatus { status })? } } pub mod built_info { // The file has been placed there by the build script. include!(concat!(env!("OUT_DIR"), "/built.rs")); }