refprop-rs
Safe Rust bindings for NIST REFPROP -- thermodynamic and transport properties of refrigerants, pure fluids, and mixtures.
Features
- Pure fluids --
Fluid::new("R134A"),Fluid::new("CO2"), ... - Predefined mixtures --
Fluid::new("R410A")(auto-loaded from.MIXfiles) - Custom mixtures --
Fluid::mixture(&[("R32", 0.5), ("R125", 0.5)]) - CoolProp-style
get()--fluid.get("D", "T", 0.0, "Q", 1.0) - Configurable units -- work in °C + bar + kg/m³ + kJ/kg, or K + kPa, or any mix
- Flash calculations -- TP, TD, TH, TS, TQ, PD, PH, PS, PQ, DH, DS, HS
- Saturation, transport, critical point, fluid info
- Thread-safe -- global mutex with automatic fluid re-setup
- Parallel computation (opt-in) --
ParallelFluidduplicates the DLL/SO per CPU core for true multi-threaded throughput via rayon FluidApitrait -- common interface forFluidandParallelFluid, write generic code that works with either backend- Dynamic loading -- no compile-time linking, just point to your REFPROP installation
Prerequisites
A licensed REFPROP installation (v9.1 or v10).
Installation
Add to your Cargo.toml:
[]
= { = "https://github.com/math-dev-24/refprop-rs" }
To enable parallel computation (optional):
[]
= { = "https://github.com/math-dev-24/refprop-rs", = ["parallel"] }
The library name is refprop, so you import it as:
use ;
// With the `parallel` feature:
use ;
Configuration
Tell the library where REFPROP is installed. Create a .env file at
the project root (or set the environment variable directly):
REFPROP_PATH='C:\Program Files (x86)\REFPROP'
The library also checks standard install locations automatically.
Quick start
Engineering units (°C, bar, kg/m³, kJ/kg)
use ;
REFPROP native units (K, kPa, mol/L, J/mol)
use Fluid;
Unit system
Choose your preferred units at construction time. All inputs and outputs are automatically converted.
Presets
| Preset | T | P | D | H | S | Viscosity | Conductivity |
|---|---|---|---|---|---|---|---|
UnitSystem::refprop() |
K | kPa | mol/L | J/mol | J/(mol·K) | µPa·s | W/(m·K) |
UnitSystem::engineering() |
°C | bar | kg/m³ | kJ/kg | kJ/(kg·K) | µPa·s | W/(m·K) |
UnitSystem::si() |
K | Pa | kg/m³ | J/kg | J/(kg·K) | Pa·s | W/(m·K) |
Custom builder
Pick only the units you care about; the rest stay at REFPROP defaults:
use ;
let units = new
.temperature
.pressure;
// density stays mol/L, energy stays J/mol, etc.
let fluid = with_units?;
let sat = fluid.saturation_t?; // 0 °C directly
println!;
Available unit choices
| Property | Options |
|---|---|
| Temperature | Kelvin, Celsius, Fahrenheit |
| Pressure | KPa, Bar, MPa, Pa, Atm, Psi |
| Density | MolPerL, KgPerM3 |
| Energy/Enthalpy | JPerMol, KJPerKg, JPerKg |
| Entropy/Cv/Cp | JPerMolK, KJPerKgK, JPerKgK |
| Viscosity | MicroPaS, MilliPaS, PaS |
| Conductivity | WPerMK, MilliWPerMK |
Mixtures
use ;
// Predefined mixture (from .MIX file)
let r410a = with_units?;
// Custom composition
let r454c = mixture_with_units?;
let p = r454c.get?;
println!;
get() -- generic property lookup
// get(output, key1, val1, key2, val2) -> f64
let density = fluid.get?;
Input pairs (order-independent)
| Pair | Description |
|---|---|
T, P |
Temperature + Pressure |
P, H |
Pressure + Enthalpy |
P, S |
Pressure + Entropy |
T, Q |
Temperature + Quality |
P, Q |
Pressure + Quality |
T, D |
Temperature + Density |
T, H |
Temperature + Enthalpy |
T, S |
Temperature + Entropy |
P, D |
Pressure + Density |
D, H |
Density + Enthalpy |
D, S |
Density + Entropy |
H, S |
Enthalpy + Entropy |
Output keys
| Key | Property |
|---|---|
T |
Temperature |
P |
Pressure |
D |
Density |
H |
Enthalpy |
S |
Entropy |
Q |
Quality (vapor frac.) |
Cv |
Heat capacity (v) |
Cp |
Heat capacity (p) |
W |
Speed of sound |
E |
Internal energy |
ETA |
Dynamic viscosity |
TCX |
Thermal conductivity |
Units depend on the UnitSystem you chose at construction time.
Flash & saturation methods
All methods respect the configured unit system.
let props = fluid.props_tp?; // TP flash
let props = fluid.props_ph?; // PH flash
let props = fluid.props_ps?; // PS flash
let props = fluid.props_tq?; // TQ flash (saturation)
let props = fluid.props_pq?; // PQ flash (saturation)
let props = fluid.props_td?; // TD flash
let props = fluid.props_th?; // TH flash
let props = fluid.props_ts?; // TS flash
let props = fluid.props_pd?; // PD flash
let props = fluid.props_dh?; // DH flash
let props = fluid.props_ds?; // DS flash
let props = fluid.props_hs?; // HS flash
let sat = fluid.saturation_t?; // saturation at T
let sat = fluid.saturation_p?; // saturation at P
let crit = fluid.critical_point?; // Tc, Pc, Dc
let trn = fluid.transport?; // viscosity, conductivity
let info = fluid.info?; // molar mass, Ttrp, Tnbp, ...
FluidApi trait -- generic code
Fluid and ParallelFluid both implement the FluidApi trait,
so you can write functions that work with either backend:
use ;
The trait includes all single-point methods: get, all flash variants
(props_tp, props_ph, ..., props_hs), saturation_t, saturation_p,
transport, critical_point, info, and converter.
Parallel-only methods (par_get, par_props_*, worker_count) remain
exclusive to ParallelFluid.
Parallel computation
Feature gate:
parallel-- addsrayonandnum_cpusas dependencies.
REFPROP (the Fortran DLL) uses global internal state, making it
impossible to call from multiple threads simultaneously.
ParallelFluid works around this by copying the shared library once
per CPU core into a temporary directory. Each copy is loaded
independently, giving it its own Fortran state. Work is then
distributed across these isolated instances via rayon.
How it works
- Detects the number of logical CPU cores (or use a custom count)
- Copies the DLL/SO/dylib N times into a temp directory
- Loads each copy as an independent
RefpropLibrary - Distributes batch computations across workers via rayon
- Cleans up temp files automatically on
Drop
Quick example
use ;
Constructors
| Constructor | Description |
|---|---|
ParallelFluid::new(name) |
Pure/predefined mix, REFPROP units, auto core count |
ParallelFluid::with_units(name, units) |
Custom units, auto core count |
ParallelFluid::with_workers(name, n) |
REFPROP units, explicit worker count |
ParallelFluid::with_units_and_workers(name, units, n) |
Full control |
ParallelFluid::mixture(comps) |
Custom mixture, REFPROP units |
ParallelFluid::mixture_with_units(comps, units) |
Custom mixture, custom units |
ParallelFluid::mixture_with_units_and_workers(comps, units, n) |
Full control |
Batch methods
| Method | Input | Output |
|---|---|---|
par_get(out, k1, &v1s, k2, &v2s) |
Two &[f64] slices |
Result<Vec<f64>> |
par_props_tp(&[(T, P)]) |
&[(f64, f64)] |
Vec<Result<ThermoProp>> |
par_props_ph(&[(P, H)]) |
&[(f64, f64)] |
Vec<Result<ThermoProp>> |
par_props_ps(&[(P, S)]) |
&[(f64, f64)] |
Vec<Result<ThermoProp>> |
par_props_tq(&[(T, Q)]) |
&[(f64, f64)] |
Vec<Result<ThermoProp>> |
par_props_pq(&[(P, Q)]) |
&[(f64, f64)] |
Vec<Result<ThermoProp>> |
All single-point methods from Fluid (get, props_tp, critical_point, etc.)
are also available on ParallelFluid.
Platform support
| OS | Library files detected |
|---|---|
| Windows 64-bit | REFPRP64.DLL, REFPROP.DLL, refprop.dll |
| Windows 32-bit | REFPROP.DLL, refprop.dll |
| Linux | librefprop.so, libREFPROP.so |
| macOS | librefprop.dylib, libREFPROP.dylib |
Project structure
refprop-rs/
├── Cargo.toml single crate: refprop-rs
├── src/
│ ├── lib.rs public API & re-exports
│ ├── fluid.rs Fluid struct (high-level API)
│ ├── pool.rs ParallelFluid (feature = "parallel")
│ ├── traits.rs FluidApi trait (common interface)
│ ├── converter.rs UnitSystem + Converter
│ ├── sys.rs low-level FFI (libloading)
│ ├── error.rs error types
│ ├── properties.rs result structs
│ └── backend/
│ └── refprop.rs REFPROP backend (flash, sat, etc.)
└── examples/
├── demo.rs engineering units showcase
├── simple.rs pure fluid, native units
├── mixture.rs predefined & custom mixtures
└── parallel.rs parallel batch computation
| Module | Role |
|---|---|
sys |
Dynamic DLL loading + raw FFI function wrappers |
converter |
UnitSystem + Converter (unit conversion) |
traits |
FluidApi trait -- common interface for generic code |
fluid |
High-level API: Fluid, get(), flash, units |
pool |
ParallelFluid -- DLL pool + rayon batch methods |
backend::refprop |
Core REFPROP calls, global & isolated state management |
License
MIT