| Crates.io | rfluids |
| lib.rs | rfluids |
| version | 0.3.0 |
| created_at | 2025-05-04 17:23:07.529192+00 |
| updated_at | 2025-12-24 21:29:56.178325+00 |
| description | 🦀 Rusty CoolProp wrapper |
| homepage | https://github.com/portyanikhin/rfluids |
| repository | https://github.com/portyanikhin/rfluids |
| max_upload_size | |
| id | 1659818 |
| size | 489,099 |
🦀 Rusty CoolProp wrapper
rfluids provides a safe, idiomatic Rust interface to CoolProp —
a comprehensive C++ library for thermophysical property calculations.
Built with type safety and ergonomics in mind, it enables precise fluid property
calculations for engineering and scientific applications.
HEOS, IF97, and other CoolProp backends, which
determine the underlying equation of state or calculation method used for thermophysical
property calculationsCoolProp configuration via type-safe
builder, with optional serde support for loading from configuration filesCoolProp dynamic libraries for all supported platformsfluid – thermophysical properties
of substances (pure fluids and mixtures)humid_air – thermophysical
properties of real humid airsubstance – types representing
CoolProp substancesio – input/output parameter types
for fluid and humid air calculationsnative – low-level and high-level
CoolProp API bindingsconfig – global configuration
management for CoolPropprelude – convenient re-exports
of commonly used types and traitsregen-bindings – regenerates FFI bindings to CoolProp (requires libclang)serde – enables serialization and deserialization support for
Config, allowing
integration with configuration management crates and file-based configurationLinux x86-64macOS AArch64macOS x86-64Windows AArch64Windows x86-64rfluids requires rustc 1.85.0 or later.
Add this to your Cargo.toml:
[dependencies]
rfluids = "0.3"
Or via command line:
cargo add rfluids
🎁 It comes with native CoolProp dynamic libraries for supported platforms. The library
required for your platform will be automatically copied to the target directory during build.
It also includes pre-generated FFI bindings, so libclang is not required for normal builds.
If you need to regenerate the FFI bindings (requires libclang), enable the
regen-bindings feature.
Add this to your Cargo.toml:
[dependencies]
rfluids = { version = "0.3", features = ["regen-bindings"] }
Or via command line:
cargo add rfluids --features regen-bindings
| ℹ️ All calculations are performed in SI units |
|---|
Specific heat [J/kg/K] of saturated water vapor at 1 atm:
use approx::assert_relative_eq;
use rfluids::prelude::*;
let mut water_vapor = Fluid::from(Pure::Water)
.in_state(FluidInput::pressure(101_325.0), FluidInput::quality(1.0))?;
assert_relative_eq!(water_vapor.specific_heat()?, 2_079.937_085_633_241, max_relative = 1e-6);
Dynamic viscosity [Pa·s] of propylene glycol aqueous solution with 60 % mass fraction at 100 kPa and -20 °C:
use approx::assert_relative_eq;
use rfluids::prelude::*;
let mut propylene_glycol = Fluid::from(BinaryMixKind::MPG.with_fraction(0.6)?)
.in_state(FluidInput::pressure(100e3), FluidInput::temperature(253.15))?;
assert_relative_eq!(
propylene_glycol.dynamic_viscosity()?,
0.139_073_910_539_388_78,
max_relative = 1e-6
);
Density [kg/m³] of ethanol aqueous solution (with ethanol 40 % mass fraction) at 200 kPa and 4 °C:
use approx::assert_relative_eq;
use rfluids::prelude::*;
let mut mix =
Fluid::try_from(CustomMix::mass_based([(Pure::Water, 0.6), (Pure::Ethanol, 0.4)])?)?
.in_state(FluidInput::pressure(200e3), FluidInput::temperature(277.15))?;
assert_relative_eq!(mix.density()?, 883.392_277_162_775_9, max_relative = 1e-6);
Wet-bulb temperature [K] of humid air at 300 m above sea level, 30 °C and 50 % relative humidity:
use approx::assert_relative_eq;
use rfluids::prelude::*;
let mut humid_air = HumidAir::new().in_state(
HumidAirInput::altitude(300.0)?,
HumidAirInput::temperature(303.15),
HumidAirInput::rel_humidity(0.5),
)?;
assert_relative_eq!(
humid_air.wet_bulb_temperature()?,
295.067_569_033_474_57,
max_relative = 1e-6
);
Fluid
and HumidAir
implement the PartialEq trait.
Equality is checked by the thermodynamic state:
use rfluids::prelude::*;
let mut humid_air = HumidAir::new().in_state(
HumidAirInput::altitude(0.0)?,
HumidAirInput::temperature(293.15),
HumidAirInput::rel_humidity(0.5),
)?;
let mut another_humid_air = HumidAir::new().in_state(
HumidAirInput::pressure(101_325.0),
HumidAirInput::temperature(293.15),
HumidAirInput::rel_humidity(0.5),
)?;
assert_eq!(humid_air, another_humid_air);
another_humid_air.update(
HumidAirInput::pressure(101_325.0),
HumidAirInput::temperature(303.15),
HumidAirInput::rel_humidity(0.5),
)?;
assert_ne!(humid_air, another_humid_air);
You can also specify a CoolProp backend for
Fluid
instead of the default one using
Fluid::builder:
use rfluids::prelude::*;
let mut water = Fluid::from(Pure::Water)
.in_state(FluidInput::pressure(101_325.0), FluidInput::temperature(293.15))?;
let mut if97_water = Fluid::builder()
.substance(Pure::Water)
.with_backend(BaseBackend::If97)
.build()?
.in_state(FluidInput::pressure(101_325.0), FluidInput::temperature(293.15))?;
// Same fluids with different backends are never equal
assert_ne!(water, if97_water);
// Different backends may yield slightly different results for the same property
assert!((water.specific_heat()? - if97_water.specific_heat()?).abs() > 1e-6);