π¦ 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.
- Rich substance library: pure fluids, incompressible fluids, predefined mixtures, binary mixtures, and custom mass- or volume-based mixtures
- Comprehensive property calculations: thermodynamic (e.g., density, enthalpy, entropy, etc.) and transport properties (e.g., viscosity, thermal conductivity, etc.)
- Psychrometric calculations: based on ASHRAE RP-1485 standard
- Flexible backends: choose between
HEOS,IF97, and otherCoolPropbackends, which determine the underlying equation of state or calculation method used for thermophysical property calculations - Type-safe API: leverages Rust's type system with the Typestate Pattern to prevent invalid operations at compile time
- Configuration management: flexible control over
CoolPropconfiguration via type-safe builder, with optionalserdesupport for loading from configuration files - Batteries included: pre-compiled
CoolPropdynamic libraries for all supported platforms
fluidβ thermophysical properties of substances (pure fluids and mixtures)humid_airβ thermophysical properties of real humid airsubstanceβ types representingCoolPropsubstancesioβ input/output parameter types for fluid and humid air calculationsnativeβ low-level and high-levelCoolPropAPI bindingsconfigβ global configuration management forCoolProppreludeβ convenient re-exports of commonly used types and traits
regen-bindingsβ regenerates FFI bindings toCoolProp(requireslibclang)serdeβ enables serialization and deserialization support forConfig, allowing integration with configuration management crates and file-based configuration
Linux AArch64Linux x86-64macOS AArch64macOS x86-64Windows AArch64Windows x86-64
rfluids requires rustc 1.85.0 or later.
Add this to your Cargo.toml:
[dependencies]
rfluids = "0.5"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.5", 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);