Merge r8f-device-loads (R8/R7 phase 2 round 1; default-off, verified)
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
@@ -650,23 +650,80 @@ fn flag_wake_on_the_device() {
|
||||
let (mut drag_sum, mut lift_min, mut lift_max, mut samples) =
|
||||
(0.0, f64::INFINITY, f64::NEG_INFINITY, 0usize);
|
||||
let mut worst_residual = 0.0_f64;
|
||||
// R8-f: `RTX_E3_LOADS_DEVICE=1` takes the operator route on the device
|
||||
// (the per-span and whole-body totals below); `RTX_E3_LOADS_CHECK=1`
|
||||
// checks the device route against the host on EVERY step (both the
|
||||
// slab's planes and the whole body), bit for bit.
|
||||
let loads_device =
|
||||
rtx_cfd::solvers::incompressible::embedded3::step::device::loads_device_enabled();
|
||||
let loads_check = std::env::var("RTX_E3_LOADS_CHECK").is_ok_and(|v| v == "1");
|
||||
let mut loads_bad = 0usize;
|
||||
for step in 0..steps {
|
||||
let r = device.advance(dt);
|
||||
worst_residual = worst_residual.max(r.final_residual);
|
||||
assert!(r.final_residual.is_finite(), "death at step {step}");
|
||||
let t = device.solver.time();
|
||||
if loads_check {
|
||||
for (name, planes) in [("slab", Some(slab)), ("whole", None)] {
|
||||
let ck = device
|
||||
.check_wall_loads(RHO * NU, planes)
|
||||
.expect("R8-f: the device route is unsupported here");
|
||||
let ok =
|
||||
ck.totals_identical && ck.items_identical && ck.r8c_identical.unwrap_or(true);
|
||||
loads_bad += usize::from(!ok);
|
||||
println!(
|
||||
" loads check step {step} t {t:.5} {name}: {} — totals host ({:+.12e}, {:+.12e}, {:+.12e}) device ({:+.12e}, {:+.12e}, {:+.12e}); items host {} ({} non-zero) device {} {}; item sums x {:+.12e}/{:+.12e} y {:+.12e}/{:+.12e}; R8-c {}; device-order rel {:.2e}; host {:.1} ms device {:.1} ms",
|
||||
if ok { "IDENTICAL" } else { "DIFFERS" },
|
||||
ck.host[0],
|
||||
ck.host[1],
|
||||
ck.host[2],
|
||||
ck.device[0],
|
||||
ck.device[1],
|
||||
ck.device[2],
|
||||
ck.host_items,
|
||||
ck.host_nonzero,
|
||||
ck.device_items,
|
||||
if ck.items_identical {
|
||||
"identical"
|
||||
} else {
|
||||
"DIFFER"
|
||||
},
|
||||
ck.host_item_sum[0],
|
||||
ck.device_item_sum[0],
|
||||
ck.host_item_sum[1],
|
||||
ck.device_item_sum[1],
|
||||
match ck.r8c_identical {
|
||||
Some(true) => "identical",
|
||||
Some(false) => "DIFFERS",
|
||||
None => "n/a",
|
||||
},
|
||||
ck.device_order_rel,
|
||||
ck.host_ms,
|
||||
ck.device_ms
|
||||
);
|
||||
}
|
||||
}
|
||||
let sample = (step + 1) % 10 == 0 || step + 1 == steps;
|
||||
let phase_due = vtk_dir.is_some()
|
||||
&& t >= last_period_start + next_phase as f64 * period / phases as f64
|
||||
&& next_phase < total_phases;
|
||||
if sample || phase_due {
|
||||
let dev = loads_device.then(|| {
|
||||
(
|
||||
device.cut_wall_force_device(RHO * NU, Some(slab)),
|
||||
device.cut_wall_force_device(RHO * NU, None),
|
||||
)
|
||||
});
|
||||
device.download(&mut field);
|
||||
let solver = &device.solver;
|
||||
let mask = solver.mask().expect("mask");
|
||||
let body = solver.body().expect("body");
|
||||
let fs = mask
|
||||
.cut_wall_force_per_span(body, &field, RHO * NU, t, slab)
|
||||
.expect("wall");
|
||||
let fs = match dev {
|
||||
Some((Some(v), _)) => v,
|
||||
_ => mask
|
||||
.cut_wall_force_per_span(body, &field, RHO * NU, t, slab)
|
||||
.expect("wall"),
|
||||
};
|
||||
// The reconstructed wall route on the same slab, per span.
|
||||
let fr = mask
|
||||
.cut_wall_force_reconstructed(body, &field, RHO * NU, t, Some(slab))
|
||||
@@ -675,9 +732,12 @@ fn flag_wake_on_the_device() {
|
||||
[v[0] / lz, v[1] / lz, v[2] / lz]
|
||||
})
|
||||
.expect("reconstructed");
|
||||
let ft = mask
|
||||
.cut_wall_force(body, &field, RHO * NU, t)
|
||||
.expect("wall");
|
||||
let ft = match dev {
|
||||
Some((_, Some(v))) => v,
|
||||
_ => mask
|
||||
.cut_wall_force(body, &field, RHO * NU, t)
|
||||
.expect("wall"),
|
||||
};
|
||||
if sample {
|
||||
samples_seen += 1;
|
||||
}
|
||||
@@ -910,4 +970,8 @@ fn flag_wake_on_the_device() {
|
||||
if let Some(t) = device.timers() {
|
||||
println!(" timers: {t:?}");
|
||||
}
|
||||
if loads_check {
|
||||
println!(" R8-f LOADS CHECK: {loads_bad} calls differ");
|
||||
assert_eq!(loads_bad, 0, "R8-f: the device route differs from the host");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user