feat: implement mass balance validation for Story 7.1
- Added port_mass_flows to Component trait and implements for core components. - Added System::check_mass_balance and integrated it into the solver. - Restored connect methods for ExpansionValve, Compressor, and Pipe to fix integration tests. - Updated Python and C bindings for validation errors. - Updated sprint status and story documentation.
This commit is contained in:
139
bindings/c/README.md
Normal file
139
bindings/c/README.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# Entropyk C FFI Bindings
|
||||
|
||||
Auto-generated C bindings for the Entropyk thermodynamic simulation library.
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
# Build the library (generates target/entropyk.h)
|
||||
cargo build --release -p entropyk-c
|
||||
|
||||
# Output files:
|
||||
# - target/release/libentropyk_ffi.a (static library)
|
||||
# - target/release/libentropyk_ffi.dylib (macOS)
|
||||
# - target/release/libentropyk_ffi.so (Linux)
|
||||
# - target/entropyk.h (C header)
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```c
|
||||
#include "entropyk.h"
|
||||
#include <stdint.h>
|
||||
|
||||
int main() {
|
||||
// Create a system
|
||||
EntropykSystem* sys = entropyk_system_create();
|
||||
|
||||
// Create components
|
||||
double compressor_coeffs[10] = {0.85, 2.5, 500.0, 1500.0, -2.5, 1.8, 600.0, 1600.0, -3.0, 2.0};
|
||||
EntropykComponent* comp = entropyk_compressor_create(compressor_coeffs, 10);
|
||||
EntropykComponent* cond = entropyk_condenser_create(5000.0);
|
||||
EntropykComponent* valve = entropyk_expansion_valve_create();
|
||||
EntropykComponent* evap = entropyk_evaporator_create(3000.0);
|
||||
|
||||
// Add components to system (returns node index, or UINT32_MAX on error)
|
||||
unsigned int comp_idx = entropyk_system_add_component(sys, comp);
|
||||
unsigned int cond_idx = entropyk_system_add_component(sys, cond);
|
||||
unsigned int valve_idx = entropyk_system_add_component(sys, valve);
|
||||
unsigned int evap_idx = entropyk_system_add_component(sys, evap);
|
||||
|
||||
if (comp_idx == UINT32_MAX || cond_idx == UINT32_MAX ||
|
||||
valve_idx == UINT32_MAX || evap_idx == UINT32_MAX) {
|
||||
printf("Failed to add component\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Connect components
|
||||
EntropykErrorCode err;
|
||||
err = entropyk_system_add_edge(sys, comp_idx, cond_idx);
|
||||
err = entropyk_system_add_edge(sys, cond_idx, valve_idx);
|
||||
err = entropyk_system_add_edge(sys, valve_idx, evap_idx);
|
||||
err = entropyk_system_add_edge(sys, evap_idx, comp_idx);
|
||||
|
||||
// Finalize the system
|
||||
err = entropyk_system_finalize(sys);
|
||||
if (err != ENTROPYK_OK) {
|
||||
printf("Finalize error: %s\n", entropyk_error_string(err));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Solve
|
||||
EntropykFallbackConfig config = {
|
||||
.newton = {100, 1e-6, false, 0},
|
||||
.picard = {500, 1e-4, 0.5}
|
||||
};
|
||||
|
||||
EntropykSolverResult* result = NULL;
|
||||
err = entropyk_solve_fallback(sys, &config, &result);
|
||||
|
||||
if (err == ENTROPYK_OK) {
|
||||
printf("Converged in %u iterations\n", entropyk_result_get_iterations(result));
|
||||
printf("Status: %d\n", entropyk_result_get_status(result));
|
||||
} else {
|
||||
printf("Solve error: %s\n", entropyk_error_string(err));
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
entropyk_result_free(result);
|
||||
entropyk_system_free(sys);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## Memory Management
|
||||
|
||||
### Ownership Rules
|
||||
|
||||
1. **Create functions** (`entropyk_*_create`) return ownership to caller
|
||||
2. **Add component** transfers ownership to the system
|
||||
3. **Solve functions** return ownership of result to caller
|
||||
4. **Free functions** must be called on all owned pointers
|
||||
|
||||
### Pairs
|
||||
|
||||
| Create Function | Free Function |
|
||||
|-----------------|---------------|
|
||||
| `entropyk_system_create` | `entropyk_system_free` |
|
||||
| `entropyk_compressor_create` | `entropyk_compressor_free` |
|
||||
| `entropyk_condenser_create` | `entropyk_component_free` |
|
||||
| `entropyk_evaporator_create` | `entropyk_component_free` |
|
||||
| `entropyk_expansion_valve_create` | `entropyk_component_free` |
|
||||
| `entropyk_economizer_create` | `entropyk_component_free` |
|
||||
| `entropyk_pipe_create` | `entropyk_component_free` |
|
||||
| `entropyk_solve_*` | `entropyk_result_free` |
|
||||
|
||||
## Error Codes
|
||||
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| `OK` | Success |
|
||||
| `NON_CONVERGENCE` | Solver did not converge |
|
||||
| `TIMEOUT` | Solver timed out |
|
||||
| `CONTROL_SATURATION` | Control variable saturated |
|
||||
| `FLUID_ERROR` | Fluid property error |
|
||||
| `INVALID_STATE` | Invalid thermodynamic state |
|
||||
| `VALIDATION_ERROR` | Validation failed |
|
||||
| `NULL_POINTER` | Null pointer passed |
|
||||
| `INVALID_ARGUMENT` | Invalid argument value |
|
||||
| `NOT_FINALIZED` | System not finalized |
|
||||
| `TOPOLOGY_ERROR` | Graph topology error |
|
||||
| `COMPONENT_ERROR` | Component error |
|
||||
|
||||
## Thread Safety
|
||||
|
||||
- Each `EntropykSystem*` is independent and can be used from different threads
|
||||
- The library is reentrant: concurrent calls with different systems are safe
|
||||
- Do NOT share a single system across threads without synchronization
|
||||
|
||||
## HIL Integration
|
||||
|
||||
The library is designed for HIL (Hardware-In-the-Loop) testing with:
|
||||
- Latency target: < 20ms round-trip
|
||||
- No dynamic allocation in solve hot path
|
||||
- C99/C++ compatible headers
|
||||
|
||||
## License
|
||||
|
||||
MIT OR Apache-2.0
|
||||
Reference in New Issue
Block a user