Entropyk/_bmad-output/implementation-artifacts/2-2-coolprop-integration-sys-crate.md

8.2 KiB

Story 2.2: CoolProp Integration (sys-crate)

Status: done

Story

As a simulation user, I want CoolProp as the primary backend, so that I get NIST-quality thermodynamic data.

Acceptance Criteria

  1. CoolProp Backend Implementation (AC: #1)

    • Implement CoolPropBackend struct wrapping CoolProp C++ library
    • All FluidBackend trait methods must work correctly
    • Results must match CoolProp 6.4+ within machine precision
  2. Static Linking via sys-crate (AC: #2)

    • Set up crates/fluids/coolprop-sys/ sys-crate
    • Configure build.rs for static compilation of CoolProp C++
    • Ensure distribution without runtime C++ dependencies
  3. Safe Rust FFI Wrappers (AC: #3)

    • Create safe Rust wrappers around raw CoolProp FFI
    • Handle error translation between C++ and Rust
    • No unsafe code exposed in public API
  4. Thermodynamic Properties (AC: #4)

    • Support property queries: density, enthalpy, entropy, specific heat
    • Support (P, T), (P, h), (P, x) state inputs
    • Handle pure fluids and mixtures

Tasks / Subtasks

  • Complete coolprop-sys sys-crate setup (continues from 2-1)
    • Finalize coolprop-sys/Cargo.toml with correct features
    • Configure static linking in build.rs
    • Generate safe FFI bindings
  • Implement CoolPropBackend struct (AC: #1)
    • Wrap CoolProp C++ calls in safe Rust
    • Implement all FluidBackend trait methods
    • Handle fluid name translation (CoolProp internal names)
  • Add error handling (AC: #3)
    • Translate CoolProp error codes to FluidError
    • Handle missing fluids gracefully
    • Handle invalid states
  • Test CoolProp backend (AC: #4)
    • Test against known values from CoolProp documentation
    • Verify precision matches within machine epsilon
    • Test all supported property types

Dev Notes

Previous Story Intelligence

From Story 2-1 (Fluid Backend Trait Abstraction):

  • The FluidBackend trait is already defined in crates/fluids/src/backend.rs
  • Trait includes property() and critical_point() methods
  • Three backends planned: CoolPropBackend, TabularBackend, TestBackend
  • Error handling pattern established with FluidError enum
  • Workspace structure created: crates/fluids/coolprop-sys/ directory exists
  • Build.rs started for CoolProp C++ compilation
  • Key learning: Sys-crate setup is complex - ensure static linking works before implementing backend

Architecture Context

C++ Integration Requirements (from Architecture):

// Sys-crate pattern location: crates/fluids/coolprop-sys/
// build.rs manages static compilation of CoolProp C++

CoolPropBackend Structure:

pub struct CoolPropBackend {
    // Wraps coolprop-sys FFI calls
    // Uses interior mutability for thread-safety if needed
}

impl FluidBackend for CoolPropBackend {
    fn property(&self, fluid: FluidId, property: Property, state: ThermoState) 
        -> Result<f64, FluidError> {
        // Translate to CoolProp internal fluid names
        // Call CoolProp C++ via sys-crate
        // Translate result/error back to Rust
    }
}

Fluid Name Translation:

  • CoolProp uses internal names (e.g., "R134a" → "R1344A")
  • Need mapping table or lookup
  • Handle case sensitivity

Workspace Structure

Location: crates/fluids/

crates/fluids/
├── Cargo.toml
├── build.rs                    # Compilation CoolProp C++
├── coolprop-sys/               # Sys-crate C++ (CONTINUE FROM 2-1)
│   ├── Cargo.toml
│   ├── build.rs               # Configure static linking
│   └── src/
│       └── lib.rs             # FFI bindings
└── src/
    ├── lib.rs
    ├── backend.rs             # FluidBackend trait (DONE in 2-1)
    ├── coolprop.rs            # FR25: CoolProp integration (THIS STORY)
    ├── tabular.rs            # FR26: Tables NIST (Story 2.3)
    ├── cache.rs              # LRU cache (Story 2.4)
    └── damping.rs            # FR29: Critical point (Story 2.6)

Technical Requirements

Sys-crate Configuration (CRITICAL):

  • Static linking required for distribution
  • build.rs must compile CoolProp C++ library
  • Use cc crate for C++ compilation
  • Configure appropriate compiler flags for static libs

FFI Safety:

  • All FFI calls must be in unsafe blocks
  • Wrap in safe public methods
  • No unsafe exposed to users of the crate

Supported Properties:

  • Density (rho)
  • Enthalpy (h)
  • Entropy (s)
  • Specific heat (cp, cv)
  • Temperature (T)
  • Pressure (P)
  • Quality (x)
  • Viscosity (optional)
  • Thermal conductivity (optional)

Supported State Inputs:

  • (P, T) - pressure & temperature
  • (P, h) - pressure & enthalpy (preferred for two-phase)
  • (P, x) - pressure & quality
  • (T, x) - temperature & quality
  • (P, s) - pressure & entropy

Error Handling Pattern

#[derive(Error, Debug)]
pub enum FluidError {
    #[error("Fluid {fluid} not found")]
    UnknownFluid { fluid: String },
    
    #[error("Invalid state for property calculation: {reason}")]
    InvalidState { reason: String },
    
    #[error("CoolProp error: {0}")]
    CoolPropError(String),
    
    #[error("Critical point not available for {fluid}")]
    NoCriticalPoint { fluid: String },
}

// From 2-1 - already defined, reuse

Testing Requirements

Required Tests:

  • Verify CoolProp backend returns expected values for R134a, R410A, CO2
  • Test all property types
  • Test all state input types
  • Compare against CoolProp documentation values
  • Test error handling for invalid fluids
  • Test mixture handling (if supported)

Validation Values (Examples from CoolProp):

// R134a at 0°C (273.15K), saturated liquid
// Expected: density ≈ 1205.97 kg/m³, h ≈ 200 kJ/kg

Project Structure Notes

Alignment with Unified Structure:

  • Follows workspace-based multi-crate architecture
  • Uses trait-based design from Story 2-1
  • Located in crates/fluids/ per project structure
  • Sys-crate pattern for CoolProp C++ integration

Dependencies:

  • Depends on crates/core for types (Pressure, Temperature, etc.)
  • Depends on Story 2-1 FluidBackend trait
  • coolprop-sys provides C++ FFI layer

References

  • Epic 2 Story 2.2: [Source: planning-artifacts/epics.md#Story 2.2]
  • Architecture C++ Integration: [Source: planning-artifacts/architecture.md#C++ Integration]
  • Architecture Fluid Backend: [Source: planning-artifacts/architecture.md#Fluid Properties Backend]
  • Story 2-1 (Previous): [Source: implementation-artifacts/2-1-fluid-backend-trait-abstraction.md]
  • NFR11: CoolProp 6.4+ compatibility [Source: planning-artifacts/epics.md#NonFunctional Requirements]
  • FR25: Load fluid properties via CoolProp [Source: planning-artifacts/epics.md#Requirements Inventory]

Dev Agent Record

Agent Model Used

opencode/minimax-m2.5-free

Debug Log References

N/A - Story just created

Completion Notes List

  • Story file created with comprehensive context from epics, architecture, and previous story
  • All acceptance criteria defined with checkboxes
  • Dev notes include architecture patterns, code examples, testing requirements
  • References to source documents provided
  • Previous story learnings incorporated (2-1)
  • Status set to ready-for-dev
  • Code review fixes applied:
    • Added #![allow(dead_code)] to coolprop-sys to suppress unused FFI warnings
    • Added lints.rust configuration to Cargo.toml for unsafe_code
    • Fixed test imports to only include what's needed

File List

  1. crates/fluids/coolprop-sys/Cargo.toml - Sys-crate configuration
  2. crates/fluids/coolprop-sys/build.rs - Build script for static linking
  3. crates/fluids/coolprop-sys/src/lib.rs - FFI bindings to CoolProp C++
  4. crates/fluids/src/coolprop.rs - CoolPropBackend implementation
  5. crates/fluids/src/lib.rs - Updated exports
  6. crates/fluids/Cargo.toml - Added coolprop-sys dependency

Change Log

  • Date: 2026-02-15 - Initial implementation of CoolPropBackend with sys-crate FFI
  • Date: 2026-02-15 - Code review fixes: Added #![allow(dead_code)] and lints.rust config

Ultimate context engine analysis completed - comprehensive developer guide created