prescribed-motion replay: the fluid's power on the flag split face by face (normal vs tangential traction; root / middle / tip thirds) beside the nodal Σ F·ḋ, and replay instants (RTX_FSI2O_SAVE + SAVE_EVERY or SAVE_AT=t1,t2,… — the step that first reaches each time) for the per-region pressure audit at one physical instant across h
CI / Test (macos-latest) (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Build CPU-Only (Explicit) (push) Canceled after 0s
CI / Python Bindings (maturin) (macos-latest) (push) Canceled after 0s
Documentation / Build API Documentation (push) Canceled after 0s
Documentation / Build User Guide (push) Canceled after 0s
CI / Build (macos-latest) (push) Canceled after 0s
CI / Distributed Training Tests (push) Canceled after 0s
CI / CI Success (push) Canceled after 0s
CI / Build (ubuntu-latest) (push) Canceled after 0s
Performance Benchmarks / Run Benchmarks (push) Canceled after 0s
CI / Format Check (push) Canceled after 0s
CI / Clippy Check (push) Canceled after 0s
CI / Python Bindings (maturin) (ubuntu-latest) (push) Canceled after 0s
CI / WASM Build + Size Check (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Build CPU-Only (Explicit) (push) Canceled after 0s
CI / Python Bindings (maturin) (macos-latest) (push) Canceled after 0s
Documentation / Build API Documentation (push) Canceled after 0s
Documentation / Build User Guide (push) Canceled after 0s
CI / Build (macos-latest) (push) Canceled after 0s
CI / Distributed Training Tests (push) Canceled after 0s
CI / CI Success (push) Canceled after 0s
CI / Build (ubuntu-latest) (push) Canceled after 0s
Performance Benchmarks / Run Benchmarks (push) Canceled after 0s
CI / Format Check (push) Canceled after 0s
CI / Clippy Check (push) Canceled after 0s
CI / Python Bindings (maturin) (ubuntu-latest) (push) Canceled after 0s
CI / WASM Build + Size Check (push) Canceled after 0s
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
f61c427b6d
commit
1562b7cbb5
@@ -409,13 +409,22 @@ fn fsi2_overset_prescribed_motion() {
|
|||||||
let mut csv = std::env::var("RTX_FSI2O_CSV").ok().map(|p| {
|
let mut csv = std::env::var("RTX_FSI2O_CSV").ok().map(|p| {
|
||||||
use std::io::Write as _;
|
use std::io::Write as _;
|
||||||
let mut f = std::fs::File::create(p).expect("csv");
|
let mut f = std::fs::File::create(p).expect("csv");
|
||||||
writeln!(f, "t,uy_tip,drag,lift,power,wall_flux,area_rate").unwrap();
|
writeln!(
|
||||||
|
f,
|
||||||
|
"t,uy_tip,drag,lift,power,wall_flux,area_rate,p_faces,p_normal,p_tangential,p_root,p_mid,p_tip"
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
f
|
f
|
||||||
});
|
});
|
||||||
let tip = fluid.interface.tip.clone();
|
let tip = fluid.interface.tip.clone();
|
||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
let mut prev_area = fluid.shared.read().unwrap().area();
|
let mut prev_area = fluid.shared.read().unwrap().area();
|
||||||
let mut window: Vec<(f64, f64, f64, f64)> = Vec::new();
|
let mut window: Vec<(f64, f64, f64, f64)> = Vec::new();
|
||||||
|
let mut faces_window: Vec<(f64, f64, f64, [f64; 3])> = Vec::new();
|
||||||
|
let save_at: Vec<f64> = std::env::var("RTX_FSI2O_SAVE_AT")
|
||||||
|
.ok()
|
||||||
|
.map(|v| v.split(',').filter_map(|x| x.trim().parse().ok()).collect())
|
||||||
|
.unwrap_or_default();
|
||||||
let mut step = 0usize;
|
let mut step = 0usize;
|
||||||
let mut t_now = t0;
|
let mut t_now = t0;
|
||||||
while t_now < t_end - 0.5 * dt {
|
while t_now < t_end - 0.5 * dt {
|
||||||
@@ -437,17 +446,83 @@ fn fsi2_overset_prescribed_motion() {
|
|||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(k, (_, f))| f.x * v_r[2 * k] + f.y * v_r[2 * k + 1])
|
.map(|(k, (_, f))| f.x * v_r[2 * k] + f.y * v_r[2 * k + 1])
|
||||||
.sum();
|
.sum();
|
||||||
|
// The same power face by face: normal vs tangential traction, and
|
||||||
|
// the flag's root / middle / tip thirds (x < 0.3667 / < 0.4833 /
|
||||||
|
// the rest, the tip arc included); the cylinder's faces excluded.
|
||||||
|
let (mut p_faces, mut p_normal, mut p_tangential) = (0.0, 0.0, 0.0);
|
||||||
|
let mut p_thirds = [0.0; 3];
|
||||||
|
{
|
||||||
|
let wall = fluid.shared.read().unwrap();
|
||||||
|
for (centre, normal, len, traction) in fluid.solver.patch().wall_tractions(
|
||||||
|
&fluid.field.patch,
|
||||||
|
rtx_cfd::mesh::PatchSide::Inner,
|
||||||
|
fluid.solver.time(),
|
||||||
|
) {
|
||||||
|
let on_cylinder =
|
||||||
|
((centre[0] - 0.2).powi(2) + (centre[1] - 0.2).powi(2)).sqrt() < 0.05 + 1e-9;
|
||||||
|
if on_cylinder {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let (u, v) = wall.velocity_at(centre[0], centre[1]);
|
||||||
|
let tn = traction[0] * normal[0] + traction[1] * normal[1];
|
||||||
|
let vn = u * normal[0] + v * normal[1];
|
||||||
|
let pf = (traction[0] * u + traction[1] * v) * len;
|
||||||
|
let pn = tn * vn * len;
|
||||||
|
p_faces += pf;
|
||||||
|
p_normal += pn;
|
||||||
|
p_tangential += pf - pn;
|
||||||
|
let third = if centre[0] < 0.3667 {
|
||||||
|
0
|
||||||
|
} else if centre[0] < 0.4833 {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
2
|
||||||
|
};
|
||||||
|
p_thirds[third] += pf;
|
||||||
|
}
|
||||||
|
}
|
||||||
let (drag, lift) = fluid.measure_force();
|
let (drag, lift) = fluid.measure_force();
|
||||||
let (_, wall_flux, _, _, poly_area) = fluid.level_and_wall_flux();
|
let (_, wall_flux, _, _, poly_area) = fluid.level_and_wall_flux();
|
||||||
|
// `RTX_FSI2O_SAVE=dir` + `RTX_FSI2O_SAVE_EVERY=N` or
|
||||||
|
// `RTX_FSI2O_SAVE_AT=t1,t2,…` (the step that first reaches each
|
||||||
|
// time): replay instants for the per-region pressure audit at one
|
||||||
|
// physical instant across h.
|
||||||
|
if let Ok(dir) = std::env::var("RTX_FSI2O_SAVE") {
|
||||||
|
let hit = save_at.iter().any(|&ts| t_now < ts && ts <= t_new + 1e-12);
|
||||||
|
if hit {
|
||||||
|
fluid
|
||||||
|
.save_instant(&dir, step + 1, &d_r, &v_r)
|
||||||
|
.expect("save instant");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let (Ok(dir), Some(every)) = (
|
||||||
|
std::env::var("RTX_FSI2O_SAVE"),
|
||||||
|
std::env::var("RTX_FSI2O_SAVE_EVERY")
|
||||||
|
.ok()
|
||||||
|
.and_then(|v| v.parse::<usize>().ok())
|
||||||
|
.filter(|&n| n > 0),
|
||||||
|
) {
|
||||||
|
if (step + 1) % every == 0 {
|
||||||
|
fluid
|
||||||
|
.save_instant(&dir, step + 1, &d_r, &v_r)
|
||||||
|
.expect("save instant");
|
||||||
|
}
|
||||||
|
}
|
||||||
let area_rate = (poly_area - prev_area) / dt;
|
let area_rate = (poly_area - prev_area) / dt;
|
||||||
prev_area = poly_area;
|
prev_area = poly_area;
|
||||||
let uy_tip = tip.iter().map(|&k| d_r[2 * k + 1]).sum::<f64>() / tip.len().max(1) as f64;
|
let uy_tip = tip.iter().map(|&k| d_r[2 * k + 1]).sum::<f64>() / tip.len().max(1) as f64;
|
||||||
if let Some(f) = csv.as_mut() {
|
if let Some(f) = csv.as_mut() {
|
||||||
use std::io::Write as _;
|
use std::io::Write as _;
|
||||||
writeln!(f, "{t_new:.6},{uy_tip:.6e},{drag:.4},{lift:.4},{power:.6e},{wall_flux:.6e},{area_rate:.6e}").unwrap();
|
writeln!(
|
||||||
|
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}",
|
||||||
|
p_thirds[0], p_thirds[1], p_thirds[2]
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
if t_new >= 13.0 {
|
if t_new >= 13.0 {
|
||||||
window.push((t_new, drag, lift, power));
|
window.push((t_new, drag, lift, power));
|
||||||
|
faces_window.push((p_faces, p_normal, p_tangential, p_thirds));
|
||||||
}
|
}
|
||||||
step += 1;
|
step += 1;
|
||||||
if step % 500 == 0 {
|
if step % 500 == 0 {
|
||||||
@@ -474,4 +549,17 @@ fn fsi2_overset_prescribed_motion() {
|
|||||||
0.5 * (lmax - lmin),
|
0.5 * (lmax - lmin),
|
||||||
start.elapsed().as_secs_f64()
|
start.elapsed().as_secs_f64()
|
||||||
);
|
);
|
||||||
|
let nf = faces_window.len().max(1) as f64;
|
||||||
|
let mean = |f: &dyn Fn(&(f64, f64, f64, [f64; 3])) -> f64| {
|
||||||
|
faces_window.iter().map(f).sum::<f64>() / nf
|
||||||
|
};
|
||||||
|
println!(
|
||||||
|
" PRESCRIBED ny = {ny} power by face over [13, 16] s: faces {:+.3} W/m (nodal {mean_power:+.3}) = normal {:+.3} + tangential {:+.3}; root {:+.3} / middle {:+.3} / tip {:+.3}",
|
||||||
|
mean(&|w| w.0),
|
||||||
|
mean(&|w| w.1),
|
||||||
|
mean(&|w| w.2),
|
||||||
|
mean(&|w| w.3[0]),
|
||||||
|
mean(&|w| w.3[1]),
|
||||||
|
mean(&|w| w.3[2])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user