- Created DOCUMENTATION.md covering core philosophy, modules, and platform specifics. - Created EXAMPLES_FULL.md with complex multi-platform usage scenarios. - Updated README.md and docs/index.md to centralize documentation links.
107 lines
3.3 KiB
Markdown
107 lines
3.3 KiB
Markdown
# Entropyk: Comprehensive Examples
|
|
|
|
This document provides deep-dive examples for various Entropyk features across different platforms.
|
|
|
|
## 1. Simple Refrigeration Cycle (Rust)
|
|
The "Hello World" of thermodynamics.
|
|
|
|
```rust
|
|
use entropyk_components::compressor::{Compressor, Ahri540Coefficients};
|
|
use entropyk_components::heat_exchanger::{Condenser, Evaporator};
|
|
use entropyk_components::expansion_valve::ExpansionValve;
|
|
use entropyk_solver::{System, FallbackConfig};
|
|
|
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
let mut system = System::new();
|
|
|
|
// 1. Create Components
|
|
let comp = Compressor::new(Ahri540Coefficients::typical(), ...)?;
|
|
let cond = Condenser::new(5000.0);
|
|
let valve = ExpansionValve::new(...)?;
|
|
let evap = Evaporator::new(3000.0);
|
|
|
|
// 2. Add to System & Connect
|
|
let n1 = system.add_component(Box::new(comp));
|
|
let n2 = system.add_component(Box::new(cond));
|
|
let n3 = system.add_component(Box::new(valve));
|
|
let n4 = system.add_component(Box::new(evap));
|
|
|
|
system.add_edge(n1, n2)?; // Comp -> Cond
|
|
system.add_edge(n2, n3)?; // Cond -> Valve
|
|
system.add_edge(n3, n4)?; // Valve -> Evap
|
|
system.add_edge(n4, n1)?; // Evap -> Comp
|
|
|
|
// 3. Finalize & Solve
|
|
system.finalize()?;
|
|
let config = FallbackConfig::default();
|
|
let result = config.solve(&system)?;
|
|
|
|
println!("Cycle COP: {}", result.cop());
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
## 2. Parameter Estimation in Python
|
|
Estimating fouling (UA reduction) from sensor data.
|
|
|
|
```python
|
|
import entropyk as ek
|
|
|
|
# Setup system with experimental targets
|
|
system = ek.System()
|
|
comp = system.add_component(ek.Compressor(...))
|
|
cond = system.add_component(ek.Condenser(ua=5000.0)) # Initial guess
|
|
|
|
# Add Inverse Control target: Discharge temperature must match sensor
|
|
system.add_constraint(target_node=cond, target_value=325.15, ... )
|
|
|
|
# Solve for the UA that makes the physics match the sensor
|
|
solver = ek.NewtonConfig(inverse_mode=True)
|
|
result = solver.solve(system)
|
|
|
|
print(f"Calculated UA: {result.component_params[cond].ua} W/K")
|
|
```
|
|
|
|
## 3. Custom Component Implementation
|
|
How to add a new physical model.
|
|
|
|
```rust
|
|
use entropyk_components::{Component, SystemState, ResidualVector, JacobianBuilder, ConnectedPort};
|
|
|
|
struct BypassValve {
|
|
opening: f64,
|
|
}
|
|
|
|
impl Component for BypassValve {
|
|
fn compute_residuals(&self, state: &SystemState, residuals: &mut ResidualVector) -> Result<(), ComponentError> {
|
|
// P_out = P_in - (k * opening^2 * flow^2)
|
|
residuals[0] = state[1] - (state[0] - self.calc_dp(state));
|
|
Ok(())
|
|
}
|
|
|
|
fn jacobian_entries(&self, state: &SystemState, jacobian: &mut JacobianBuilder) -> Result<(), ComponentError> {
|
|
// Provide partial derivatives for fast convergence
|
|
jacobian.add_entry(0, 0, self.dp_dm(state));
|
|
jacobian.add_entry(0, 1, 1.0);
|
|
Ok(())
|
|
}
|
|
|
|
fn n_equations(&self) -> usize { 1 }
|
|
fn get_ports(&self) -> &[ConnectedPort] { &self.ports }
|
|
}
|
|
```
|
|
|
|
## 4. Multi-Circuit Coupling
|
|
Bridging a Chiller to a Water loop.
|
|
|
|
```rust
|
|
// Evaporator acts as a bridge
|
|
let evaporator = HeatExchanger::new_bridge(ua);
|
|
|
|
system.add_edge(refrigerant_valve, evaporator.side_a_in)?;
|
|
system.add_edge(evaporator.side_a_out, refrigerant_comp)?;
|
|
|
|
system.add_edge(water_pump, evaporator.side_b_in)?;
|
|
system.add_edge(evaporator.side_b_out, water_building)?;
|
|
```
|