Update project structure and configurations
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
//!
|
||||
//! Provides JavaScript-friendly wrappers for thermodynamic components.
|
||||
|
||||
use entropyk_components::port::{Connected, FluidId, Port};
|
||||
use entropyk_components::port::{FluidId, Port};
|
||||
use entropyk_components::Component;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
@@ -10,30 +10,39 @@ use wasm_bindgen::prelude::*;
|
||||
#[wasm_bindgen]
|
||||
pub struct WasmComponent {
|
||||
pub(crate) inner: Box<dyn Component>,
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl WasmComponent {
|
||||
/// Get component name.
|
||||
/// Get component type name.
|
||||
pub fn name(&self) -> String {
|
||||
// This is a simplification; the real Component trait doesn't have name()
|
||||
// but the System stores it. For now, we'll just return a placeholder or
|
||||
// store it in the wrapper if needed.
|
||||
"Component".to_string()
|
||||
self.name.clone()
|
||||
}
|
||||
}
|
||||
|
||||
/// WASM wrapper for Compressor.
|
||||
#[wasm_bindgen]
|
||||
pub struct WasmCompressor {
|
||||
pub(crate) inner: entropyk_components::Compressor<Connected>,
|
||||
pub(crate) inner: entropyk_components::Compressor<entropyk_components::port::Connected>,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl WasmCompressor {
|
||||
/// Create a new Compressor component.
|
||||
/// Create a new Compressor with AHRI 540 performance model.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `fluid` - Fluid identifier (e.g. "R134a", "R410A")
|
||||
/// * `speed_rpm` - Rotational speed in RPM
|
||||
/// * `displacement_m3_per_rev` - Displacement volume in m³/rev
|
||||
/// * `efficiency` - Mechanical efficiency (0.0 to 1.0)
|
||||
/// * `m1`..`m10` - AHRI 540 performance coefficients
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(
|
||||
fluid: String,
|
||||
speed_rpm: f64,
|
||||
displacement_m3_per_rev: f64,
|
||||
efficiency: f64,
|
||||
m1: f64,
|
||||
m2: f64,
|
||||
m3: f64,
|
||||
@@ -44,31 +53,49 @@ impl WasmCompressor {
|
||||
m8: f64,
|
||||
m9: f64,
|
||||
m10: f64,
|
||||
) -> WasmCompressor {
|
||||
) -> Result<WasmCompressor, JsValue> {
|
||||
if speed_rpm <= 0.0 {
|
||||
return Err(js_sys::Error::new("speed_rpm must be positive").into());
|
||||
}
|
||||
if displacement_m3_per_rev <= 0.0 {
|
||||
return Err(js_sys::Error::new("displacement_m3_per_rev must be positive").into());
|
||||
}
|
||||
if !(0.0..=1.0).contains(&efficiency) {
|
||||
return Err(js_sys::Error::new("efficiency must be between 0.0 and 1.0").into());
|
||||
}
|
||||
|
||||
let coeffs =
|
||||
entropyk_components::Ahri540Coefficients::new(m1, m2, m3, m4, m5, m6, m7, m8, m9, m10);
|
||||
let fluid_id = FluidId::new("R410A");
|
||||
let p = entropyk_core::Pressure::from_bar(10.0);
|
||||
let fluid_id = FluidId::new(&fluid);
|
||||
let p = entropyk_core::Pressure::from_bar(5.0);
|
||||
let h = entropyk_core::Enthalpy::from_joules_per_kg(400000.0);
|
||||
let suction = Port::new(fluid_id.clone(), p, h);
|
||||
let discharge = Port::new(fluid_id, p, h);
|
||||
let discharge = Port::new(fluid_id.clone(), p, h);
|
||||
|
||||
let comp =
|
||||
entropyk_components::Compressor::new(coeffs, suction, discharge, 2900.0, 0.0001, 0.85)
|
||||
.unwrap();
|
||||
let comp = entropyk_components::Compressor::new(
|
||||
coeffs,
|
||||
suction,
|
||||
discharge,
|
||||
speed_rpm,
|
||||
displacement_m3_per_rev,
|
||||
efficiency,
|
||||
)
|
||||
.map_err(|e| js_sys::Error::new(&format!("Compressor creation failed: {}", e)))?;
|
||||
|
||||
// Connect to dummy ports to get Connected state
|
||||
let suction_p = Port::new(FluidId::new("R410A"), p, h);
|
||||
let discharge_p = Port::new(FluidId::new("R410A"), p, h);
|
||||
let connected = comp.connect(suction_p, discharge_p).unwrap();
|
||||
let suction_p = Port::new(fluid_id.clone(), p, h);
|
||||
let discharge_p = Port::new(fluid_id, p, h);
|
||||
let connected = comp
|
||||
.connect(suction_p, discharge_p)
|
||||
.map_err(|e| js_sys::Error::new(&format!("Compressor connect failed: {}", e)))?;
|
||||
|
||||
WasmCompressor { inner: connected }
|
||||
Ok(WasmCompressor { inner: connected })
|
||||
}
|
||||
|
||||
/// Convert to a generic WasmComponent.
|
||||
pub fn into_component(self) -> WasmComponent {
|
||||
WasmComponent {
|
||||
inner: Box::new(self.inner),
|
||||
name: "Compressor".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,18 +108,27 @@ pub struct WasmCondenser {
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl WasmCondenser {
|
||||
/// Create a new condenser with thermal conductance UA.
|
||||
/// Create a new condenser with thermal conductance UA (W/K).
|
||||
///
|
||||
/// Rejects NaN, negative, zero, and infinite values.
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(ua: f64) -> WasmCondenser {
|
||||
WasmCondenser {
|
||||
inner: entropyk_components::Condenser::new(ua),
|
||||
pub fn new(ua: f64) -> Result<WasmCondenser, JsValue> {
|
||||
if ua.is_nan() || ua.is_infinite() {
|
||||
return Err(js_sys::Error::new("UA must be a finite number").into());
|
||||
}
|
||||
if ua <= 0.0 {
|
||||
return Err(js_sys::Error::new("UA must be positive").into());
|
||||
}
|
||||
Ok(WasmCondenser {
|
||||
inner: entropyk_components::Condenser::new(ua),
|
||||
})
|
||||
}
|
||||
|
||||
/// Convert to a generic WasmComponent.
|
||||
pub fn into_component(self) -> WasmComponent {
|
||||
WasmComponent {
|
||||
inner: Box::new(self.inner),
|
||||
name: "Condenser".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,18 +141,27 @@ pub struct WasmEvaporator {
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl WasmEvaporator {
|
||||
/// Create a new evaporator with thermal conductance UA.
|
||||
/// Create a new evaporator with thermal conductance UA (W/K).
|
||||
///
|
||||
/// Rejects NaN, negative, zero, and infinite values.
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(ua: f64) -> WasmEvaporator {
|
||||
WasmEvaporator {
|
||||
inner: entropyk_components::Evaporator::new(ua),
|
||||
pub fn new(ua: f64) -> Result<WasmEvaporator, JsValue> {
|
||||
if ua.is_nan() || ua.is_infinite() {
|
||||
return Err(js_sys::Error::new("UA must be a finite number").into());
|
||||
}
|
||||
if ua <= 0.0 {
|
||||
return Err(js_sys::Error::new("UA must be positive").into());
|
||||
}
|
||||
Ok(WasmEvaporator {
|
||||
inner: entropyk_components::Evaporator::new(ua),
|
||||
})
|
||||
}
|
||||
|
||||
/// Convert to a generic WasmComponent.
|
||||
pub fn into_component(self) -> WasmComponent {
|
||||
WasmComponent {
|
||||
inner: Box::new(self.inner),
|
||||
name: "Evaporator".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,33 +169,42 @@ impl WasmEvaporator {
|
||||
/// WASM wrapper for ExpansionValve.
|
||||
#[wasm_bindgen]
|
||||
pub struct WasmExpansionValve {
|
||||
pub(crate) inner: entropyk_components::ExpansionValve<Connected>,
|
||||
pub(crate) inner: entropyk_components::ExpansionValve<entropyk_components::port::Connected>,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl WasmExpansionValve {
|
||||
/// Create a new expansion valve.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `fluid` - Fluid identifier (e.g. "R134a", "R410A")
|
||||
/// * `capacity` - Optional valve capacity (kW). Pass 0.0 for no capacity limit.
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new() -> WasmExpansionValve {
|
||||
let fluid_id = FluidId::new("R410A");
|
||||
pub fn new(fluid: String, capacity: f64) -> Result<WasmExpansionValve, JsValue> {
|
||||
let fluid_id = FluidId::new(&fluid);
|
||||
let p = entropyk_core::Pressure::from_bar(10.0);
|
||||
let h = entropyk_core::Enthalpy::from_joules_per_kg(400000.0);
|
||||
let inlet = Port::new(fluid_id.clone(), p, h);
|
||||
let outlet = Port::new(fluid_id, p, h);
|
||||
let outlet = Port::new(fluid_id.clone(), p, h);
|
||||
|
||||
let valve = entropyk_components::ExpansionValve::new(inlet, outlet, Some(1.0)).unwrap();
|
||||
let cap = if capacity > 0.0 { Some(capacity) } else { None };
|
||||
let valve = entropyk_components::ExpansionValve::new(inlet, outlet, cap)
|
||||
.map_err(|e| js_sys::Error::new(&format!("ExpansionValve creation failed: {}", e)))?;
|
||||
|
||||
let inlet_p = Port::new(FluidId::new("R410A"), p, h);
|
||||
let outlet_p = Port::new(FluidId::new("R410A"), p, h);
|
||||
let connected = valve.connect(inlet_p, outlet_p).unwrap();
|
||||
let inlet_p = Port::new(fluid_id.clone(), p, h);
|
||||
let outlet_p = Port::new(fluid_id, p, h);
|
||||
let connected = valve
|
||||
.connect(inlet_p, outlet_p)
|
||||
.map_err(|e| js_sys::Error::new(&format!("ExpansionValve connect failed: {}", e)))?;
|
||||
|
||||
WasmExpansionValve { inner: connected }
|
||||
Ok(WasmExpansionValve { inner: connected })
|
||||
}
|
||||
|
||||
/// Convert to a generic WasmComponent.
|
||||
pub fn into_component(self) -> WasmComponent {
|
||||
WasmComponent {
|
||||
inner: Box::new(self.inner),
|
||||
name: "ExpansionValve".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,38 +212,60 @@ impl WasmExpansionValve {
|
||||
/// WASM wrapper for Pipe.
|
||||
#[wasm_bindgen]
|
||||
pub struct WasmPipe {
|
||||
pub(crate) inner: entropyk_components::Pipe<Connected>,
|
||||
pub(crate) inner: entropyk_components::Pipe<entropyk_components::port::Connected>,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl WasmPipe {
|
||||
/// Create a new pipe.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `fluid` - Fluid identifier (e.g. "Water")
|
||||
/// * `length` - Pipe length in meters (must be positive)
|
||||
/// * `diameter` - Pipe inner diameter in meters (must be positive)
|
||||
/// * `density` - Fluid density in kg/m³ (default: 1000.0 for water)
|
||||
/// * `viscosity` - Fluid dynamic viscosity in Pa·s (default: 0.001 for water)
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(length: f64, diameter: f64) -> WasmPipe {
|
||||
let geometry = entropyk_components::PipeGeometry::smooth(length, diameter).unwrap();
|
||||
let fluid_id = FluidId::new("Water");
|
||||
pub fn new(
|
||||
fluid: String,
|
||||
length: f64,
|
||||
diameter: f64,
|
||||
density: f64,
|
||||
viscosity: f64,
|
||||
) -> Result<WasmPipe, JsValue> {
|
||||
if length.is_nan() || length <= 0.0 {
|
||||
return Err(js_sys::Error::new("Pipe length must be a positive number").into());
|
||||
}
|
||||
if diameter.is_nan() || diameter <= 0.0 {
|
||||
return Err(js_sys::Error::new("Pipe diameter must be a positive number").into());
|
||||
}
|
||||
|
||||
let geometry = entropyk_components::PipeGeometry::smooth(length, diameter)
|
||||
.map_err(|e| js_sys::Error::new(&format!("Invalid pipe geometry: {}", e)))?;
|
||||
|
||||
let fluid_id = FluidId::new(&fluid);
|
||||
let p = entropyk_core::Pressure::from_bar(1.0);
|
||||
let h = entropyk_core::Enthalpy::from_joules_per_kg(100000.0);
|
||||
let inlet = Port::new(fluid_id.clone(), p, h);
|
||||
let outlet = Port::new(fluid_id, p, h);
|
||||
let outlet = Port::new(fluid_id.clone(), p, h);
|
||||
|
||||
let pipe = entropyk_components::Pipe::new(
|
||||
geometry, inlet, outlet, 1000.0, // Default density
|
||||
0.001, // Default viscosity
|
||||
)
|
||||
.unwrap();
|
||||
let pipe = entropyk_components::Pipe::new(geometry, inlet, outlet, density, viscosity)
|
||||
.map_err(|e| js_sys::Error::new(&format!("Pipe creation failed: {}", e)))?;
|
||||
|
||||
let inlet_p = Port::new(FluidId::new("Water"), p, h);
|
||||
let outlet_p = Port::new(FluidId::new("Water"), p, h);
|
||||
let connected = pipe.connect(inlet_p, outlet_p).unwrap();
|
||||
let inlet_p = Port::new(fluid_id.clone(), p, h);
|
||||
let outlet_p = Port::new(fluid_id, p, h);
|
||||
let connected = pipe
|
||||
.connect(inlet_p, outlet_p)
|
||||
.map_err(|e| js_sys::Error::new(&format!("Pipe connect failed: {}", e)))?;
|
||||
|
||||
WasmPipe { inner: connected }
|
||||
Ok(WasmPipe { inner: connected })
|
||||
}
|
||||
|
||||
/// Convert to a generic WasmComponent.
|
||||
pub fn into_component(self) -> WasmComponent {
|
||||
WasmComponent {
|
||||
inner: Box::new(self.inner),
|
||||
name: "Pipe".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user