From e3958fc9c57c913d15be5d0f44bb5f03ceb3ccec Mon Sep 17 00:00:00 2001 From: Omar Sobh Date: Sun, 20 Sep 2026 17:55:41 -0500 Subject: [PATCH] =?UTF-8?q?embedded3=20PERF-3=20P1-5=20(a)(b):=20the=20pre?= =?UTF-8?q?vious-step=20aperture/volume=20records=20move=20out=20of=20the?= =?UTF-8?q?=20old=20mask=20instead=20of=20being=20cloned;=20the=20GCL=20ta?= =?UTF-8?q?ble=20over=20the=20changed=20cells=20and=20the=20wall=20cells?= =?UTF-8?q?=20(the=20serial=20sums=20with=20their=20exact-zero=20terms=20l?= =?UTF-8?q?eft=20out,=20same=20order)=20=E2=80=94=20slab=20flag=20ny=2062?= =?UTF-8?q?=20CSV=20byte-identical,=20device=20moving/cg=20green;=20ny=201?= =?UTF-8?q?24=20rebuild=20block=201,995=20=E2=86=92=201,895=20ms=20per=20s?= =?UTF-8?q?tep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- .../incompressible/embedded3/cutwall.rs | 35 ++++++++++++++--- .../incompressible/embedded3/step/moving.rs | 38 ++++++++++++------- 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/crates/specialized/rtx-cfd/src/solvers/incompressible/embedded3/cutwall.rs b/crates/specialized/rtx-cfd/src/solvers/incompressible/embedded3/cutwall.rs index b167cfa..38d627e 100644 --- a/crates/specialized/rtx-cfd/src/solvers/incompressible/embedded3/cutwall.rs +++ b/crates/specialized/rtx-cfd/src/solvers/incompressible/embedded3/cutwall.rs @@ -679,12 +679,31 @@ impl Mask { let g = self.grid; let dv = g.dx * g.dy * g.dz; let (mut net, mut area) = (0.0, 0.0); - for (idx, entry) in table.iter_mut().enumerate() { + // P1-5 (b): a cell untouched by this build has the old volume (its + // entry is exactly 0 and adds nothing to `net`); a cell without a + // wall adds nothing to `area`. The sums run over the changed cells + // and the wall cells in ascending order — the serial loop's order + // with its zero terms left out, bit for bit. + let wall_cells: Vec = { + use rayon::prelude::*; + (0..table.len()) + .into_par_iter() + .filter(|&idx| self.cell_active(idx) && cut.wall[idx] != [0.0; 3]) + .collect() + }; + let cells: Vec = match self.changed_cells.as_deref() { + Some(changed) => changed.to_vec(), + None => (0..table.len()).collect(), + }; + for &idx in &cells { if !self.cell_active(idx) { continue; } - *entry = (cut.vol[idx] - old_cut.vol[idx]) * dv / dt; - net += *entry; + let entry = (cut.vol[idx] - old_cut.vol[idx]) * dv / dt; + table[idx] = entry; + net += entry; + } + for &idx in &wall_cells { let w = cut.wall[idx]; area += (w[0] * w[0] + w[1] * w[1] + w[2] * w[2]).sqrt(); } @@ -703,9 +722,13 @@ impl Mask { } let correction = if area > 0.0 { net / area } else { 0.0 }; if correction != 0.0 { - for (idx, w) in cut.wall.iter().enumerate() { - let a = (w[0] * w[0] + w[1] * w[1] + w[2] * w[2]).sqrt(); - table[idx] -= correction * a; + // Every cell with a wall (the others subtract exactly 0). + for idx in 0..table.len() { + let w = cut.wall[idx]; + if w != [0.0; 3] { + let a = (w[0] * w[0] + w[1] * w[1] + w[2] * w[2]).sqrt(); + table[idx] -= correction * a; + } } } (table, correction) diff --git a/crates/specialized/rtx-cfd/src/solvers/incompressible/embedded3/step/moving.rs b/crates/specialized/rtx-cfd/src/solvers/incompressible/embedded3/step/moving.rs index 9b7b739..43931c5 100644 --- a/crates/specialized/rtx-cfd/src/solvers/incompressible/embedded3/step/moving.rs +++ b/crates/specialized/rtx-cfd/src/solvers/incompressible/embedded3/step/moving.rs @@ -72,19 +72,31 @@ impl Solver { self.last_ghost_correction = correction; } let s_gcl = sub.elapsed(); - if let Some(old) = &self.mask { - self.apertures_old = old - .cut() - .map(|c| [c.a_u.clone(), c.a_v.clone(), c.a_w.clone()]); - self.vol_old = (0..field.grid.cells()) - .map(|i| { - if old.is_fluid_cell(i) { - old.vol(i) - } else { - 0.0 - } - }) - .collect(); + // P1-5 (a): the old mask is replaced below — its arrays MOVE into + // the previous-step records instead of being cloned (1 GB per step + // at ny 124); the values are the same. + if let Some(mut old) = self.mask.take() { + let fluid = std::mem::take(&mut old.cell_fluid); + if let Some(c) = old.cut.as_mut() { + self.apertures_old = Some([ + std::mem::take(&mut c.a_u), + std::mem::take(&mut c.a_v), + std::mem::take(&mut c.a_w), + ]); + let mut vol = std::mem::take(&mut c.vol); + use rayon::prelude::*; + vol.par_iter_mut() + .zip(fluid.par_iter()) + .for_each(|(v, &f)| { + if !f { + *v = 0.0; + } + }); + self.vol_old = vol; + } else { + self.apertures_old = None; + self.vol_old = vec![0.0; field.grid.cells()]; + } } if std::env::var("RTX_E3_MOVING_PROFILE").is_ok() { let ms = |d: std::time::Duration| d.as_secs_f64() * 1e3;