feat(python): implement python bindings for all components and solvers

This commit is contained in:
Sepehr
2026-02-21 20:34:56 +01:00
parent 8ef8cd2eba
commit 4440132b0a
310 changed files with 11577 additions and 397 deletions

View File

@@ -17,13 +17,7 @@ fn coolprop_src_path() -> Option<PathBuf> {
PathBuf::from("/opt/CoolProp"),
];
for path in possible_paths {
if path.join("CMakeLists.txt").exists() {
return Some(path);
}
}
None
possible_paths.into_iter().find(|path| path.join("CMakeLists.txt").exists())
}
fn main() {

View File

@@ -177,7 +177,9 @@ extern "C" {
/// * `fluid` - Fluid name (e.g., "R134a")
///
/// # Returns
/// The property value in SI units, or NaN if an error occurs
/// # Safety
/// This function calls the CoolProp C++ library and passes a CString pointer.
/// The caller must ensure the fluid string is properly null-terminated if needed and valid.
pub unsafe fn props_si_pt(property: &str, p: f64, t: f64, fluid: &str) -> f64 {
let prop = property.as_bytes()[0] as c_char;
let fluid_c = CString::new(fluid).unwrap();
@@ -194,7 +196,9 @@ pub unsafe fn props_si_pt(property: &str, p: f64, t: f64, fluid: &str) -> f64 {
/// * `fluid` - Fluid name
///
/// # Returns
/// The property value in SI units, or NaN if an error occurs
/// # Safety
/// This function calls the CoolProp C++ library and passes a CString pointer.
/// The caller must ensure the fluid string is valid.
pub unsafe fn props_si_ph(property: &str, p: f64, h: f64, fluid: &str) -> f64 {
let prop = property.as_bytes()[0] as c_char;
let fluid_c = CString::new(fluid).unwrap();
@@ -211,7 +215,9 @@ pub unsafe fn props_si_ph(property: &str, p: f64, h: f64, fluid: &str) -> f64 {
/// * `fluid` - Fluid name
///
/// # Returns
/// The property value in SI units, or NaN if an error occurs
/// # Safety
/// This function calls the CoolProp C++ library and passes a CString pointer.
/// The caller must ensure the fluid string is valid.
pub unsafe fn props_si_tq(property: &str, t: f64, q: f64, fluid: &str) -> f64 {
let prop = property.as_bytes()[0] as c_char;
let fluid_c = CString::new(fluid).unwrap();
@@ -228,7 +234,9 @@ pub unsafe fn props_si_tq(property: &str, t: f64, q: f64, fluid: &str) -> f64 {
/// * `fluid` - Fluid name
///
/// # Returns
/// The property value in SI units, or NaN if an error occurs
/// # Safety
/// This function calls the CoolProp C++ library and passes a CString pointer.
/// The caller must ensure the fluid string is valid.
pub unsafe fn props_si_px(property: &str, p: f64, x: f64, fluid: &str) -> f64 {
let prop = property.as_bytes()[0] as c_char;
let fluid_c = CString::new(fluid).unwrap();
@@ -249,7 +257,9 @@ pub unsafe fn props_si_px(property: &str, p: f64, x: f64, fluid: &str) -> f64 {
/// * `fluid` - Fluid name
///
/// # Returns
/// Critical temperature in K, or NaN if unavailable
/// # Safety
/// This function calls the CoolProp C++ library and passes a CString pointer.
/// The caller must ensure the fluid string is valid.
pub unsafe fn critical_temperature(fluid: &str) -> f64 {
let fluid_c = CString::new(fluid).unwrap();
CoolProp_CriticalPoint(fluid_c.as_ptr(), b'T' as c_char)
@@ -261,7 +271,9 @@ pub unsafe fn critical_temperature(fluid: &str) -> f64 {
/// * `fluid` - Fluid name
///
/// # Returns
/// Critical pressure in Pa, or NaN if unavailable
/// # Safety
/// This function calls the CoolProp C++ library and passes a CString pointer.
/// The caller must ensure the fluid string is valid.
pub unsafe fn critical_pressure(fluid: &str) -> f64 {
let fluid_c = CString::new(fluid).unwrap();
CoolProp_CriticalPoint(fluid_c.as_ptr(), b'P' as c_char)
@@ -273,7 +285,9 @@ pub unsafe fn critical_pressure(fluid: &str) -> f64 {
/// * `fluid` - Fluid name
///
/// # Returns
/// Critical density in kg/m³, or NaN if unavailable
/// # Safety
/// This function calls the CoolProp C++ library and passes a CString pointer.
/// The caller must ensure the fluid string is valid.
pub unsafe fn critical_density(fluid: &str) -> f64 {
let fluid_c = CString::new(fluid).unwrap();
CoolProp_CriticalPoint(fluid_c.as_ptr(), b'D' as c_char)
@@ -285,7 +299,9 @@ pub unsafe fn critical_density(fluid: &str) -> f64 {
/// * `fluid` - Fluid name
///
/// # Returns
/// `true` if the fluid is available
/// # Safety
/// This function calls the CoolProp C++ library and passes a CString pointer.
/// The caller must ensure the fluid string is valid.
pub unsafe fn is_fluid_available(fluid: &str) -> bool {
let fluid_c = CString::new(fluid).unwrap();
CoolProp_isfluid(fluid_c.as_ptr()) != 0
@@ -299,7 +315,7 @@ pub fn get_version() -> String {
unsafe {
let mut buffer = vec![0u8; 32];
let result = CoolProp_get_global_param_string(
b"version\0".as_ptr() as *const c_char,
c"version".as_ptr(),
buffer.as_mut_ptr() as *mut c_char,
buffer.len() as c_int,
);

View File

@@ -21,8 +21,7 @@ use std::num::NonZeroUsize;
/// Default cache capacity (entries). LRU eviction when exceeded.
pub const DEFAULT_CACHE_CAPACITY: usize = 10_000;
/// Default capacity as NonZeroUsize for LruCache (avoids unwrap in production path).
const DEFAULT_CAP_NONZERO: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(DEFAULT_CACHE_CAPACITY) };
const DEFAULT_CAP_NONZERO: NonZeroUsize = NonZeroUsize::new(DEFAULT_CACHE_CAPACITY).unwrap();
/// Quantization factor: values rounded to 1e-9 relative.
/// (v * 1e9).round() as i64 for Hash-compatible key.

View File

@@ -177,7 +177,7 @@ impl IncompressibleBackend {
),
});
}
if concentration < 0.0 || concentration > 0.6 {
if !(0.0..=0.6).contains(&concentration) {
return Err(FluidError::InvalidState {
reason: format!(
"Glycol concentration {} outside valid range [0, 0.6]",