Skip to content

thermalogic/RustSEUIF97

Repository files navigation

SEUIF97

docs.rs Build test Crates.io Version Crates.io Total Downloads Crates.io Downloads (recent)PyPI Downloads Downloads npm versionNPM DownloadsNPM Downloads

This is the Rust implementation of the high-speed IAPWS-IF97 package SEUIF97 with C, Python and WASM bindings. It is designed for computation-intensive tasks, such as simulating non-stationary processes, on-line process monitoring, and optimization.

Through the high-speed package, IAPWS-IF97 calculations achieve a 5-20x speedup compared to direct implementations using the Rust standard library's powi() within loops for the basic equations of Regions 1, 2 and 3.

This package supports 12 distinct input state pairs for calculating 36 thermodynamic, transport, and derived properties (see Properties), and thermodynamic process functions (see Thermodynamic Process Functions).

Acceleration Methods

  • Loop Tiling: Unleashes the full power of compiler optimizations, surpassing the performance of the single loop.
  • Shared-Power Scaling: By leveraging the mathematical relationship between polynomials and their derivatives, we compute shared power terms only once. Subsequent results are derived through exponent scaling, thereby eliminating redundant calculations and significantly improving computational efficiency

Please refer to The acceleration methods for more details on the algorithm

What's New in the Rust Version

The Rust version of SEUIF97 is a major upgrade over the original C implementation, delivering significant improvements in performance, functionality, and ecosystem support.

Feature C Version Rust Version
Calculation Speed Baseline ~2× speedup
Supported Properties 30 properties 36 properties (+6 new)
Package Distribution PyPI only Crates.io, PyPI, npm
Direct Property Functions (new)

For detailed comparison and key improvements, see Rust vs C Version Comparison.

Install the crate

cargo add seuif97

Property Calculation Functions

The package provides two types of API for property calculation.

  1. Universal Functions (with o_id and optional region parameter)
    • These functions accept an input property pair plus a property ID(o_id) to calculate the desired output property. For example: pt(p,t,o_id,<region>), where o_id specifies the output property, and region is optional.
  2. Direct Property Functions
    • These functions directly calculate a specific property (p,t,h,s,v,x) from the input property pairs without requiring the property ID parameter. For example: pt2h(p,t).

C, Python and WASM bindings support all functions of both types in Rust, except for the optional region parameter.

Universal Functions (with o_id and <optional> region parameter)

The following function signature is provided:

struct o_id_region_args {
   o_id: i32,
   region: i32,
}

fn<R>(f64,f64,R) -> f64
where
    R: Into<o_id_region_args>,
  • the first,second input parameters(f64) : the input property pairs
  • the third and fourth input parameters:
    • the third : the property ID of the calculated property - o_id
    • the fourth (optional) parameter: IAPWS-IF97 region specification
  • the return(f64): the calculated property value of o_id

The following 12 input pairs are implemented:

pt<R>(p:f64,t:f64,o_id_region:R)->f64
ph<R>(p:f64,h:f64,o_id_region:R)->f64
ps<R>(p:f64,s:f64,o_id_region:R)->f64
pv<R>(p:f64,v:f64,o_id_region:R)->f64

th<R>(t:f64,h:f64,o_id_region:R)->f64
ts<R>(t:f64,s:f64,o_id_region:R)->f64
tv<R>(t:f64,v:f64,o_id_region:R)->f64

hs<R>(h:f64,s:f64,o_id_region:R)->f64

px(p:f64,x:f64,o_id:i32)->f64
tx(p:f64,x:f64,o_id:i32)->f64
hx(h:f64,x:f64,o_id:i32)->f64
sx(s:f64,x:f64,o_id:i32)->f64

Direct Property Functions

The following 12 input pairs are implemented:

pt2h(p, t)  pt2s(p, t)  pt2v(p, t)  pt2x(p, t)
ph2t(p, h)  ph2s(p, h)  ph2v(p, h)  ph2x(p, h)   
ps2t(p, s)  ps2h(p, s)  ps2v(p, s)  ps2x(p, s)  
pv2t(p, v)  pv2h(p, v)  pv2s(p, v)  pv2x(p, v)  

th2p(t, h)  th2s(t, h)  th2v(t, h)  th2x(t, h)   
ts2p(t, s)  ts2h(t, s)  ts2v(t, s)  ts2x(t, s)  
tv2p(t, v)  tv2h(t, v)  tv2s(t, v)  tv2x(t, v)  

hs2p(h, s)  hs2t(h, s)  hs2v(h, s)  hs2x(h, s)    

px2t(p, x)  px2h(p, x)  px2s(p, x)  px2v(p, x)
tx2p(t, x)  tx2h(t, x)  tx2s(t, x)  tx2v(t, x)

hx2p(h, x)  hx2t(h, x)  hx2s(h, x)  hx2v(h, x)
sx2p(s, x)  sx2t(s, x)  sx2h(s, x)  sx2v(s, x)

Thermodynamic Process Functions

The following thermodynamic process functions are implemented:

ishd(pi:f64, ti:f64, pe:f64) -> f64    // Isentropic enthalpy drop (kJ/kg)
ief(pi:f64, ti:f64, pe:f64, te:f64) -> f64  // Isentropic efficiency (%)
  • ishd: Calculates the isentropic enthalpy drop for steam expansion from inlet state (pi, ti) to outlet pressure pe.
  • ief: Calculates the isentropic efficiency (%) for superheated steam expansion from inlet state (pi, ti) to outlet state (pe, te).

Usage

use seuif97::*;
fn main() {
    
    let p:f64 = 3.0;
    let t:f64= 300.0-273.15;
    // universal functions (with o_id parameter only)
    let h=pt(p,t,OH);
    // universal functions with explicit region for faster calculation
    let s=pt(p,t,(OS,1));
    // direct property functions
    let v=pt2v(p,t);

    println!("p={p:.6} t={t:.6} h={h:.6} s={s:.6} v={v:.6}");   

    // thermodynamic process functions
    let pi: f64 = 16.0;
    let ti: f64 = 535.1;
    let pe: f64 = 5.0;
    let delta_h = ishd(pi, ti, pe);
    println!("ishd: pi={pi} ti={ti} pe={pe} delta_h={delta_h:.3}");
}

C Shared Library

Building the dynamic link library

  • cdecl
cargo build -r --features cdecl
  • stdcall: Windows API functions(MSVC 64bit)
cargo build -r --features stdcall
  • stdcall: Windows API functions(MSVC 32bit)
cargo build -r  --target=i686-pc-windows-msvc --features stdcall

Pre-compiled dynamic link libraries for Windows, Linux and macOS are available in GitHub Releases.

Legacy pre-compiled libraries are also provided in the ./dynamic_lib/ directory.

The shared library supports all functions of both types in Rust, except for the optional region parameter. For example in C:

double pt(double p,double t,short o_id);
double pt2s(double p,double t);

Interfaces and examples are provided in the ./demo_using_lib/ directory, supporting a wide range of languages and environments

  • C/C++, Python, C#, Java, Excel VBA, Rust, Fortran, Golang, JavaScript/TypeScript
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define OH 4

extern double pt(double p,double t,short o_id);
extern double pt2s(double p,double t);

int main(void)
{
    double p = 16.0;
    double t = 530.0;
    // universal functions (with o_id parameter only)
    double h = pt(p, t, OH);
    // direct property functions
    double s = pt2s(p, t);
    printf("p,t %f,%f h= %f s= %f\n", p, t, h, s);
    return EXIT_SUCCESS;
}

Comprehensive Cross-language Examples

Python binding

Install from pypi

pip install seuif97
from seuif97 import *

OH=4

p=16.0
t=535.1
# universal functions (with o_id parameter only)
h=pt(p,t,OH)
# direct property functions
s=pt2s(p,t)
print(f"p={p}, t={t} h={h:.3f} s={s:.3f}")

The Comprehensive Examples in Python

T-S Diagram

WASM binding

import init, { pt, pt2s } from 'seuif97';

await init();

const p = 16.0;  // MPa
const t = 535.1; // °C
// universal functions (with o_id parameter only)
const h = pt(p, t, 4);     // kJ/kg
// direct property functions
const s = pt2s(p, t);      // kJ/(kg·K)

console.log('Properties at p = 16.0 MPa, t = 535.1 °C:');
console.log(`H: ${h.toFixed(3)} kJ/kg`);
console.log(`S: ${s.toFixed(5)} kJ/(kg·K)`);

Properties

Property Unit Symbol o_id o_id(i32)
Pressure MPa p OP 0
Temperature °C t OT 1
Density kg/m³ ρ OD 2
Specific Volume m³/kg v OV 3
Specific enthalpy kJ/kg h OH 4
Specific entropy kJ/(kg·K) s OS 5
Specific exergy kJ/kg e OE 6
Specific internal energy kJ/kg u OU 7
Specific isobaric heat capacity kJ/(kg·K) cp OCP 8
Specific isochoric heat capacity kJ/(kg·K) cv OCV 9
Speed of sound m/s w OW 10
Isentropic exponent
k OKS 11
Specific Helmholtz free energy kJ/kg f OF 12
Specific Gibbs free energy kJ/kg g OG 13
Compressibility factor
z OZ 14
Steam quality
x OX 15
Region
r OR 16
Isobaric cubic expansion coefficient 1/K ɑv OEC 17
Isothermal compressibility 1/MPa kT OKT 18
Partial derivative (∂V/∂T)p m³/(kg·K) (∂V/∂T)p ODVDT 19
Partial derivative (∂V/∂p)T m³/(kg·MPa) (∂v/∂p)t ODVDP 20
Partial derivative (∂P/∂T)v MPa/K (∂p/∂t)v ODPDT 21
Isothermal throttling coefficient kJ/(kg·MPa) δt OIJTC 22
Joule-Thomson coefficient K/MPa μ OJTC 23
Dynamic viscosity Pa·s η ODV 24
Kinematic viscosity m²/s ν OKV 25
Thermal conductivity W/(m.K) λ OTC 26
Thermal diffusivity m²/s a OTD 27
Prandtl number
Pr OPR 28
Surface tension N/m σ OST 29
Static Dielectric Constant
ε OSDC 30
Isochoric pressure coefficient 1/K β OPC 31
Isothermal stress coefficient kg/m³ βp OBETAP 32
Fugacity coefficient
fi OFI 33
Fugacity MPa f* OFU 34
Relative pressure coefficient 1/K αp OAFLAP 35

About

The high-speed IAPWS-IF97 package in Rust with C, Python and WASM bindings

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors