Entropyk/EXAMPLES_FULL.md
Sepehr 56df96ed9e docs: create comprehensive documentation and deep-dive examples
- 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.
2026-02-21 23:25:04 +01:00

3.3 KiB

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.

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.

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.

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.

// 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)?;