R8-c: drop zero summands from cut_wall_loads; extrapolation diagnostics beyond FAR_OUTSIDE with the worst point
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
9c2ae32061
commit
05bf4c74a0
@@ -79,18 +79,17 @@ impl Mask {
|
||||
if self.grad_weights.is_some() {
|
||||
return None;
|
||||
}
|
||||
// The loops visit every fluid cell and face; only the non-zero
|
||||
// summands are loads (the zero ones change no sum).
|
||||
let mut raw: Vec<(LoadKind, [f64; 3], [f64; 3])> = Vec::new();
|
||||
let (p, s) = self
|
||||
.cut_wall_force_parts_sink(body, f, mu, t, None, &mut |k, x, v| raw.push((k, x, v)))?;
|
||||
let (d, c) = self.cut_wall_exchange_parts_sink(
|
||||
body,
|
||||
f,
|
||||
mu,
|
||||
self.density,
|
||||
t,
|
||||
None,
|
||||
&mut |k, x, v| raw.push((k, x, v)),
|
||||
)?;
|
||||
let mut keep = |k: LoadKind, x: [f64; 3], v: [f64; 3]| {
|
||||
if v != [0.0; 3] {
|
||||
raw.push((k, x, v));
|
||||
}
|
||||
};
|
||||
let (p, s) = self.cut_wall_force_parts_sink(body, f, mu, t, None, &mut keep)?;
|
||||
let (d, c) =
|
||||
self.cut_wall_exchange_parts_sink(body, f, mu, self.density, t, None, &mut keep)?;
|
||||
let xch = [d[0] + c[0], d[1] + c[1], d[2] + c[2]];
|
||||
let total = [
|
||||
p[0] + s[0] + xch[0],
|
||||
@@ -209,6 +208,10 @@ pub struct Location {
|
||||
pub outside: f64,
|
||||
}
|
||||
|
||||
/// The natural-coordinate distance outside an element from which a load
|
||||
/// counts as extrapolated in [`PlateTransfer`] (0.02 of the half-element).
|
||||
pub const FAR_OUTSIDE: f64 = 0.02;
|
||||
|
||||
/// The result of one load transfer (see [`HexPlate::transfer`]).
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PlateTransfer {
|
||||
@@ -223,9 +226,13 @@ pub struct PlateTransfer {
|
||||
/// The largest Newton residual (m) and the largest outside-ness.
|
||||
pub max_residual: f64,
|
||||
pub max_outside: f64,
|
||||
/// Loads located outside every element (extrapolated), and their Σ|F|.
|
||||
/// Loads located outside every element by more than [`FAR_OUTSIDE`]
|
||||
/// in natural coordinates (a foot off the plate by more than a few %
|
||||
/// of an element — the surfaces' round-off-level mismatch is excluded),
|
||||
/// their Σ|F|, and the worst one's point.
|
||||
pub extrapolated: usize,
|
||||
pub extrapolated_load: f64,
|
||||
pub worst_point: [f64; 3],
|
||||
/// The share of Σ|f_a| on nodes off the wetted surface (the interior
|
||||
/// layers and the clamped root face).
|
||||
pub interior_share: f64,
|
||||
@@ -481,6 +488,7 @@ impl HexPlate {
|
||||
let (mut force_in, mut moment_in) = ([0.0f64; 3], [0.0f64; 3]);
|
||||
let (mut max_residual, mut max_outside) = (0.0f64, f64::NEG_INFINITY);
|
||||
let (mut extrapolated, mut extrapolated_load) = (0usize, 0.0f64);
|
||||
let mut worst_point = [0.0f64; 3];
|
||||
for (&(p, f), loc) in loads.iter().zip(&located) {
|
||||
for (&n, &w) in loc.nodes.iter().zip(&loc.weights) {
|
||||
for c in 0..3 {
|
||||
@@ -493,8 +501,11 @@ impl HexPlate {
|
||||
moment_in[c] += m[c];
|
||||
}
|
||||
max_residual = max_residual.max(loc.residual);
|
||||
max_outside = max_outside.max(loc.outside);
|
||||
if loc.outside > 1e-9 {
|
||||
if loc.outside > max_outside {
|
||||
max_outside = loc.outside;
|
||||
worst_point = p;
|
||||
}
|
||||
if loc.outside > FAR_OUTSIDE {
|
||||
extrapolated += 1;
|
||||
extrapolated_load += norm(f);
|
||||
}
|
||||
@@ -524,6 +535,7 @@ impl HexPlate {
|
||||
max_outside,
|
||||
extrapolated,
|
||||
extrapolated_load,
|
||||
worst_point,
|
||||
interior_share: if total_abs > 0.0 {
|
||||
interior_abs / total_abs
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user