overset: the stamp-energy instrument (P5-3's energy-source measurement) — OversetResult gains stamp_energy (½ρ(u_stamped² − u_before²)·dx·dy summed over the fringe faces after the flux balance on a reclassification step) and reclass_energy (the faces touching a cell whose class changed); the replay CSV logs both plus the reclassified-cell count per step — the comparator showed the plate loads per unit motion agree with ours to ~10 %, so the discrepancy is our limit-cycle amplitude, an h-growing energy source, and the hole boundary's reclassification is the candidate
CI / CI Success (push) Failing after 0s
CI / Build (macos-latest) (push) Failing after 16s
CI / Test (macos-latest) (push) Skipped
CI / Test (ubuntu-latest) (push) Skipped
CI / Python Bindings (maturin) (macos-latest) (push) Skipped
CI / Python Bindings (maturin) (ubuntu-latest) (push) Skipped
CI / WASM Build + Size Check (push) Skipped
CI / Distributed Training Tests (push) Skipped
Documentation / Build User Guide (push) Successful in 13s
CI / Format Check (push) Failing after 19s
CI / Clippy Check (push) Failing after 5s
Performance Benchmarks / Run Benchmarks (push) Failing after 6s
Documentation / Build API Documentation (push) Failing after 7s
CI / Build CPU-Only (Explicit) (push) Failing after 1m24s
CI / Build (ubuntu-latest) (push) Failing after 2m2s
CI / CI Success (push) Failing after 0s
CI / Build (macos-latest) (push) Failing after 16s
CI / Test (macos-latest) (push) Skipped
CI / Test (ubuntu-latest) (push) Skipped
CI / Python Bindings (maturin) (macos-latest) (push) Skipped
CI / Python Bindings (maturin) (ubuntu-latest) (push) Skipped
CI / WASM Build + Size Check (push) Skipped
CI / Distributed Training Tests (push) Skipped
Documentation / Build User Guide (push) Successful in 13s
CI / Format Check (push) Failing after 19s
CI / Clippy Check (push) Failing after 5s
Performance Benchmarks / Run Benchmarks (push) Failing after 6s
Documentation / Build API Documentation (push) Failing after 7s
CI / Build CPU-Only (Explicit) (push) Failing after 1m24s
CI / Build (ubuntu-latest) (push) Failing after 2m2s
Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_0116sg1Qz1gMv9hdcKP1XUam
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
796b8487ad
commit
914d369efe
@@ -134,6 +134,14 @@ pub struct OversetResult {
|
|||||||
pub reclassified_cells: usize,
|
pub reclassified_cells: usize,
|
||||||
/// Background cells that jumped hole → active (patch moved > 1 cell).
|
/// Background cells that jumped hole → active (patch moved > 1 cell).
|
||||||
pub fresh_cells: usize,
|
pub fresh_cells: usize,
|
||||||
|
/// Kinetic energy the exchange wrote into the background's fringe faces
|
||||||
|
/// on this step's reclassification (`½ ρ (u_stamped² − u_before²)` per
|
||||||
|
/// face times `dx·dy`, summed over the stamped `u` and `v` faces after
|
||||||
|
/// the fringe flux balance) [J/m]; 0 when the patch did not move.
|
||||||
|
pub stamp_energy: f64,
|
||||||
|
/// The part of `stamp_energy` on faces that touch a cell whose class
|
||||||
|
/// changed in this rebuild — the reclassification's own share.
|
||||||
|
pub reclass_energy: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Restorable state of the composite (the coupling re-runs a step).
|
/// Restorable state of the composite (the coupling re-runs a step).
|
||||||
@@ -510,6 +518,7 @@ impl OversetPisoSolver {
|
|||||||
// path to the bit.
|
// path to the bit.
|
||||||
let mut reclassified = 0usize;
|
let mut reclassified = 0usize;
|
||||||
let mut fresh = 0usize;
|
let mut fresh = 0usize;
|
||||||
|
let (mut stamp_energy, mut reclass_energy) = (0.0_f64, 0.0_f64);
|
||||||
// P3b locating trace (print-only, `RTX_OVERSET_TRACE_SP`): the class
|
// P3b locating trace (print-only, `RTX_OVERSET_TRACE_SP`): the class
|
||||||
// of every background cell before this step, kept only when a
|
// of every background cell before this step, kept only when a
|
||||||
// reclassification happens.
|
// reclassification happens.
|
||||||
@@ -581,11 +590,10 @@ impl OversetPisoSolver {
|
|||||||
// instead of taking the patch's interpolation when they turn
|
// instead of taking the patch's interpolation when they turn
|
||||||
// prescribed.
|
// prescribed.
|
||||||
let h1 = std::env::var("RTX_OVERSET_H1").is_ok();
|
let h1 = std::env::var("RTX_OVERSET_H1").is_ok();
|
||||||
|
let u_before = field.background.u.clone();
|
||||||
|
let v_before = field.background.v.clone();
|
||||||
let (u_keep, v_keep) = if h1 {
|
let (u_keep, v_keep) = if h1 {
|
||||||
(
|
(Some(u_before.clone()), Some(v_before.clone()))
|
||||||
Some(field.background.u.clone()),
|
|
||||||
Some(field.background.v.clone()),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
(None, None)
|
(None, None)
|
||||||
};
|
};
|
||||||
@@ -606,6 +614,31 @@ impl OversetPisoSolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.balance_fringe(&mut field.background);
|
self.balance_fringe(&mut field.background);
|
||||||
|
// The energy the stamp wrote (P5-3's energy-source instrument):
|
||||||
|
// every stamped face, and the faces touching a reclassified cell.
|
||||||
|
{
|
||||||
|
let rho = self.background.config().density;
|
||||||
|
let vol = dx * dy;
|
||||||
|
let changed = |jj: usize, ii: usize| {
|
||||||
|
jj < ny && ii < nx && old_map.class(jj, ii) != self.overlap.class(jj, ii)
|
||||||
|
};
|
||||||
|
for e in &self.overlap.fringe_u {
|
||||||
|
let (a, b) = (u_before[(e.j, e.i)], field.background.u[(e.j, e.i)]);
|
||||||
|
let de = 0.5 * rho * (b * b - a * a) * vol;
|
||||||
|
stamp_energy += de;
|
||||||
|
if changed(e.j, e.i) || (e.i > 0 && changed(e.j, e.i - 1)) {
|
||||||
|
reclass_energy += de;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for e in &self.overlap.fringe_v {
|
||||||
|
let (a, b) = (v_before[(e.j, e.i)], field.background.v[(e.j, e.i)]);
|
||||||
|
let de = 0.5 * rho * (b * b - a * a) * vol;
|
||||||
|
stamp_energy += de;
|
||||||
|
if changed(e.j, e.i) || (e.j > 0 && changed(e.j - 1, e.i)) {
|
||||||
|
reclass_energy += de;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// Knock-out H2 (`RTX_OVERSET_H2`): cells that turn active → fringe
|
// Knock-out H2 (`RTX_OVERSET_H2`): cells that turn active → fringe
|
||||||
// keep the background's own pressure this step instead of the
|
// keep the background's own pressure this step instead of the
|
||||||
// patch's stamped value (their p' is still Dirichlet from the
|
// patch's stamped value (their p' is still Dirichlet from the
|
||||||
@@ -805,6 +838,8 @@ impl OversetPisoSolver {
|
|||||||
overlap_flux_scale: scale,
|
overlap_flux_scale: scale,
|
||||||
reclassified_cells: reclassified,
|
reclassified_cells: reclassified,
|
||||||
fresh_cells: fresh,
|
fresh_cells: fresh,
|
||||||
|
stamp_energy,
|
||||||
|
reclass_energy,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -411,7 +411,7 @@ fn fsi2_overset_prescribed_motion() {
|
|||||||
let mut f = std::fs::File::create(p).expect("csv");
|
let mut f = std::fs::File::create(p).expect("csv");
|
||||||
writeln!(
|
writeln!(
|
||||||
f,
|
f,
|
||||||
"t,uy_tip,drag,lift,power,wall_flux,area_rate,p_faces,p_normal,p_tangential,p_root,p_mid,p_tip,rounds_max,schwarz_ok,bg_residual,patch_div,defect_patch,defect_bg"
|
"t,uy_tip,drag,lift,power,wall_flux,area_rate,p_faces,p_normal,p_tangential,p_root,p_mid,p_tip,rounds_max,schwarz_ok,bg_residual,patch_div,defect_patch,defect_bg,reclassified,e_stamp,e_reclass"
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
f
|
f
|
||||||
@@ -436,12 +436,15 @@ fn fsi2_overset_prescribed_motion() {
|
|||||||
if let Err(e) = fluid.set_geometry(&d_r, &v_r) {
|
if let Err(e) = fluid.set_geometry(&d_r, &v_r) {
|
||||||
panic!("set_geometry died at step {step}, t = {t_new:.4}: {e:?}");
|
panic!("set_geometry died at step {step}, t = {t_new:.4}: {e:?}");
|
||||||
}
|
}
|
||||||
let (rounds_max, schwarz_ok, bg_res, patch_div) = match fluid.step() {
|
let (rounds_max, schwarz_ok, bg_res, patch_div, reclassified, e_stamp, e_reclass) = match fluid.step() {
|
||||||
Ok(r) => (
|
Ok(r) => (
|
||||||
r.rounds.iter().copied().max().unwrap_or(0),
|
r.rounds.iter().copied().max().unwrap_or(0),
|
||||||
r.schwarz_converged,
|
r.schwarz_converged,
|
||||||
r.background_residual,
|
r.background_residual,
|
||||||
r.patch_max_divergence,
|
r.patch_max_divergence,
|
||||||
|
r.reclassified_cells,
|
||||||
|
r.stamp_energy,
|
||||||
|
r.reclass_energy,
|
||||||
),
|
),
|
||||||
Err(e) => panic!("fluid step died at step {step}, t = {t_new:.4}: {e:?}"),
|
Err(e) => panic!("fluid step died at step {step}, t = {t_new:.4}: {e:?}"),
|
||||||
};
|
};
|
||||||
@@ -522,7 +525,7 @@ fn fsi2_overset_prescribed_motion() {
|
|||||||
use std::io::Write as _;
|
use std::io::Write as _;
|
||||||
writeln!(
|
writeln!(
|
||||||
f,
|
f,
|
||||||
"{t_new:.6},{uy_tip:.6e},{drag:.4},{lift:.4},{power:.6e},{wall_flux:.6e},{area_rate:.6e},{p_faces:.6e},{p_normal:.6e},{p_tangential:.6e},{:.6e},{:.6e},{:.6e},{rounds_max},{},{bg_res:.3e},{patch_div:.3e},{defect_patch:.3e},{defect_bg:.3e}",
|
"{t_new:.6},{uy_tip:.6e},{drag:.4},{lift:.4},{power:.6e},{wall_flux:.6e},{area_rate:.6e},{p_faces:.6e},{p_normal:.6e},{p_tangential:.6e},{:.6e},{:.6e},{:.6e},{rounds_max},{},{bg_res:.3e},{patch_div:.3e},{defect_patch:.3e},{defect_bg:.3e},{reclassified},{e_stamp:.4e},{e_reclass:.4e}",
|
||||||
p_thirds[0], p_thirds[1], p_thirds[2], schwarz_ok as u8
|
p_thirds[0], p_thirds[1], p_thirds[2], schwarz_ok as u8
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user