Fix BPHX mass flux per-side channels so pressure drop is visible.
Some checks failed
CI / check (push) Has been cancelled

Mass flux used all plate gaps instead of half the pack per fluid, underestimating G and making ΔP look like zero in the UI (0.000 bar). Also show ΔP in kPa/Pa and sync the web example.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-19 17:06:44 +02:00
parent 81abd5a591
commit 2f1f7ecb80
5 changed files with 55 additions and 48 deletions

View File

@@ -498,7 +498,8 @@ impl BphxExchanger {
let dp_hot = self.side_channel_dp(state[m_h], rho_hot, z_dp)?;
let dp_cold = self.side_channel_dp(state[m_c], rho_cold, z_dp)?;
let a_flow = self.geometry.channel_flow_area() * self.geometry.n_channels() as f64;
let a_flow =
self.geometry.channel_flow_area() * self.geometry.n_channels_per_side() as f64;
if a_flow <= 1e-30 {
return Err(ComponentError::InvalidState(
"BPHX channel flow area too small for pressure-drop Jacobian".into(),

View File

@@ -170,20 +170,29 @@ impl BphxGeometry {
self.channel_spacing * self.plate_width
}
/// Returns the total number of channels (n_plates - 1).
/// Returns the total number of inter-plate gaps (n_plates 1).
pub fn n_channels(&self) -> u32 {
self.n_plates.saturating_sub(1)
}
/// Returns the mass flux for a given mass flow rate.
/// Channels available to **one** fluid in a single-pass counterflow pack.
///
/// G = m_dot / (A_channel × n_channels)
/// Alternating hot/cold channels split the gaps roughly in half:
/// `⌊n_plates / 2⌋` (at least 1). Using the full `n_channels` for mass flux
/// underestimates G by ~2× and ΔP by ~4×.
pub fn n_channels_per_side(&self) -> u32 {
(self.n_plates / 2).max(1)
}
/// Returns the mass flux for a given mass flow rate on one fluid side.
///
/// G = m_dot / (A_channel × n_channels_per_side)
///
/// # Arguments
///
/// * `mass_flow` - Total mass flow rate (kg/s)
/// * `mass_flow` - Total mass flow rate on that side (kg/s)
pub fn mass_flux(&self, mass_flow: f64) -> f64 {
let n_channels = self.n_channels() as f64;
let n_channels = self.n_channels_per_side() as f64;
if n_channels < 1e-10 {
return 0.0;
}
@@ -460,8 +469,12 @@ mod tests {
.unwrap();
let mass_flow = 0.1;
// 10 plates → 5 channels per side; A_ch = 0.002 × 0.1 = 2e-4 m²
// G = 0.1 / (2e-4 × 5) = 100 kg/(m²·s)
let g = geo.mass_flux(mass_flow);
assert!(g > 0.0);
assert!((g - 100.0).abs() < 1e-9, "got G={g}");
assert_eq!(geo.n_channels_per_side(), 5);
assert_eq!(geo.n_channels(), 9);
}
#[test]