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

250 lines
8.2 KiB
Markdown

# Story 2.2: CoolProp Integration (sys-crate)
Status: done
<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
## 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)
- [x] Implement `CoolPropBackend` struct wrapping CoolProp C++ library
- [x] All `FluidBackend` trait methods must work correctly
- [x] Results must match CoolProp 6.4+ within machine precision
2. **Static Linking via sys-crate** (AC: #2)
- [x] Set up `crates/fluids/coolprop-sys/` sys-crate
- [x] Configure `build.rs` for static compilation of CoolProp C++
- [x] Ensure distribution without runtime C++ dependencies
3. **Safe Rust FFI Wrappers** (AC: #3)
- [x] Create safe Rust wrappers around raw CoolProp FFI
- [x] Handle error translation between C++ and Rust
- [x] No unsafe code exposed in public API
4. **Thermodynamic Properties** (AC: #4)
- [x] Support property queries: density, enthalpy, entropy, specific heat
- [x] Support (P, T), (P, h), (P, x) state inputs
- [x] Handle pure fluids and mixtures
## Tasks / Subtasks
- [x] Complete coolprop-sys sys-crate setup (continues from 2-1)
- [x] Finalize `coolprop-sys/Cargo.toml` with correct features
- [x] Configure static linking in `build.rs`
- [x] Generate safe FFI bindings
- [x] Implement CoolPropBackend struct (AC: #1)
- [x] Wrap CoolProp C++ calls in safe Rust
- [x] Implement all FluidBackend trait methods
- [x] Handle fluid name translation (CoolProp internal names)
- [x] Add error handling (AC: #3)
- [x] Translate CoolProp error codes to FluidError
- [x] Handle missing fluids gracefully
- [x] Handle invalid states
- [x] Test CoolProp backend (AC: #4)
- [x] Test against known values from CoolProp documentation
- [x] Verify precision matches within machine epsilon
- [x] 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):**
```rust
// Sys-crate pattern location: crates/fluids/coolprop-sys/
// build.rs manages static compilation of CoolProp C++
```
**CoolPropBackend Structure:**
```rust
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
```rust
#[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):**
```rust
// 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**