Files
CelerisLab/research/j3-reservoir-2026-10-12/REVIEW.md
T

13 KiB
Raw Blame History

J3 顶部压力库:实现前物理契约与冻结门槛

2026-10-12。本次是已授权试验的单次恢复。重新读取仓库,HEAD与当前216个文件哈希记录在baseline.json,不沿用历史核对代替现状。root唯一代码写入与测试者。.agents为空且无.agents/skills;使用现有.github/skills/lbm-ref-architecture-guard/SKILL.md。保留J1、J2原始结果/失败和所有旧修改;不提交推送、改环境、访问其他项目或安装依赖。

参考、推导、范围

已读取主源Zou–He §3与§3.1,并搜索核对本地ref/OpenLB/src/boundary/zouHeDynamics.hh:67–118的未知分布重建/切向矩修正,及本库core/descriptors.cuh:24–25方向表。参考要点:给定密度及沿边界速度可解法向速度;non-equilibrium法向反射补闭合;边界到达态重建后仍碰撞;方向必须按本库重新编号。仅普通D2Q9:sum(f)=rho、sum(cf)=rhou,不采用§3.3 d2q9i的动量定义。论文双精度测试不覆盖本FP32案例。

顶部在y=NY−2,未知{4,6,7},已知{0,1,2,3,5,8}。令P=f3+f5+f8、Z=f0+f1+f2、S=Z+2P。已知rho=rho0与切向u=0,由质量与y动量得J_y=S−rho0、v=J_y/rho0。正v沿+y流出,负v流入。闭合为:

f4 = f3 − (2/3)*J_y
f6 = f5 + (f1−f2)/2 − J_y/6
f7 = f8 + (f2−f1)/2 − J_y/6

独立代回:sum(f)=Z+2P−J_y=rho0;sum(cxf)=0;sum(cyf)=J_y。实现直接用J_y避免不必要的v除法再乘rho;不以旧velocity helper重算指定密度。helper只改三个未知方向,无碰撞/存储/全局质量反馈。

新增唯一opt-in配置method.top_wall_bc="reservoir",默认"velocity"保持J1/J2。仅允许现有on_site_velocity受限组合且physics.velocity=0;固定顶rho使用已有physics.rho,不新增重复密度参数。顶模式、固定rho(仅reservoir)和现有固定切向速度纳入状态签名与checkpoint匹配;旧checkpoint缺top_wall_bc按velocity。checkpoint v3结构不变。

底部quartic slot/零速flanks、幅值/归一与y物理面不变。仍是pull g(t)→arrival f(t+dt)→重建未知→SRT→g(t+dt)。仅step顶部选择新helper,无新增生产launch。修改边界限定config、compiler临时宏、planar helper、已有one_step_double、checkpoint、CONFIG及针对性测试/验证器。旧helper公式和初始化数值路径不改。

初始化沿J2:rho=rho0、u=0,v由底profile线性插值到顶的均匀Q/NX。这个顶v只是初始猜测;从第一步起由已知populations和rho0局部求v,可随x变化,不同时强制Q/NX。

冻结验收(任何本包测试运行前)

  • D2Q9/SRT/FP32/unshifted/double-buffer、无物体/力/LES、单GPU单层;NX48/NY35/H32/W16、nu=.1、U=0、rho0=1、先A=+.002。Q=.01706689453125,仅为底部请求体积;top初始猜测.000355560302734375,不作后续目标。
  • 采样519步,至少8间隔,最多40间隔=20760步。沿J2完整u/v场各RMS变化/固定速度尺度max(|A|,.002)≤5e−5,连续末4间隔。每间隔相对初始质量变化≤2e−6;末4间隔质量跨度≤6e−6;初末相对质量偏移≤1e−3。门槛、步数不放宽。
  • 实际新CUDA helper CPUshim:rho0=1/1.04,顶部法向v=0/±.001/±.01,平衡及扰动已知输入;三个未知输入毒化。已知方向逐值保持;独立质量rho0、切向动量0、法向动量S−rho0误差各≤3e−7;平衡保持≤3e−7。不能仅对照helper自身计算值。
  • 新边界GPU宏观检查:底profile法向及底/顶切向最大速度误差≤2e−6;顶部max|rho−rho0|/rho0≤5e−7(明确为本FP32规模容差);顶u=0包含在上述2e−6中。独立记录所有顶节点rho/u/v,不要求顶v均匀或等于旧Q/NX。
  • 内部距底8/16/24处实际Σrhov,相对rho_barQ误差≤.005,三个截面跨度/|rho_barQ|≤.002;同时记录各y实际Σv与Σrhov。所有populations有限,rho最大偏差≤.005、max速度≤.01。零幅值max速度≤2e−6。
  • x镜像rho/v偶、u奇:rho误差/rho0≤2e−5;u/v误差/固定.002≤.002。非零案例内部中心v与A同号,max|u|>1e−5。保留完整实际场、质量历史,不以目标自证实际通量。
  • 每例末态另16步:包括slot、零目标flanks、整个顶部的实际population incoming/outgoing;实际collision舍入单列;独立ΔM预算残差/M≤2e−7;审计版与普通版逐值相同。预算闭合不能替代稳态质量通过。
  • 先CPU和旧路径短回归:原J1全平面与原J2有限slot旧velocity-top同初态64步DDF/flags与本包起点逐值相同;默认关闭7步对照亦逐值相同。新顶模式/固定rho不一致、静态签名改变及旧缺省字段的配置/checkpoint契约在CPU核对。
  • 然后仅跑正例;若正例失败即停止,不运行负例/零幅值/新模式GPU恢复,分别标未测。正例全部通过后才补同参数A=−.002、A=0及正例短checkpoint恢复延续;每项必须有明确通过/失败/未测,null不得算通过。

这是新的顶部物理条件;即使通过,压力库可能带走数值舍入新增质量,不能说collision舍入消失,或旧失败全部来自连续模型,也不推论所有2D双速度边界无稳态。未增加clipping、renormalization、动态反馈、FP64、曲面或AMR。

运行固定cwd=/home/frank14f/CelerisLab、既有解释器/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python、进程PYTHONPATH=/home/frank14f/CelerisLab/src;核对真实Python/CUDA来源。GPU只在空闲获准0/1中选取,每次启动前检查。保留原始日志、命令和本轮增量,完成后停止。当前尚未执行本包测试。

结果:正例未通过速度收敛,按约定停止

以上为运行前冻结记录。所有模型参数、门槛和最大步数均未调整。新顶部压力库实现完成,但正例在20760步上限内没有满足完整速度场的连续四间隔收敛判据,进程明确退出1。负例、零幅值和新模式GPU checkpoint延续均为 not_tested,没有将跳过项计作通过。

检查 结果 证据
CPU helper/配置/状态/checkpoint契约 通过 111 passed、13 subtests passed,4.58秒
原J1 velocity-top,初始化及64步 通过 与本轮起点DDF/flags逐值相同
原J2有限slot velocity-top,初始化及64步 通过 与本轮起点DDF/flags逐值相同
默认关闭短通道,7步 通过 与本轮起点DDF/flags逐值相同
reservoir正例完整场稳态 失败 末4间隔v变化均超过5e−5
正例质量、流量、范围、边界矩、镜像 通过 下面列出数值,完整场和历史见results.json
实际16步population预算 通过 审计/普通版逐值一致,预算残差0
reservoir负例/零幅值/GPU恢复 未测 正例失败触发预定停止条件

CPU新helper覆盖20组:rho=1/1.04、法向v=0/±.001/±.01、平衡/非平衡。独立检查rho、两个动量矩及已知方向保持;未知输入毒化。配置/checkpoint测试覆盖非法模式、错误边界组合、非零顶切向速度、非法密度、模式/rho/u不一致在写状态前拒绝、旧缺省字段仅对应velocity、同模式host恢复。新模式GPU恢复未运行,不能用host测试代替它。

实际速度与质量历史

底部请求Q=.01706689453125;顶部初猜.000355560302734375。末态顶Cartesian v范围[.0002525877428643851, .00046274994794326185],平均.00035590787330683823,随x变化,未强制旧Q/NX。顶rho范围[.9999998677521944, 1.0000002067536116],最大相对误差2.06754e−7≤5e−7;顶切向max|u|=9.31323e−9。底/顶已指定速度最大误差3.66936e−8≤2e−6。

最后间隔结束步数 u场RMS变化/.002 v场RMS变化/.002 质量相对初始增量
19203 2.63806e−5 7.32955e−5 2.20613e−8
19722 2.68569e−5 6.99404e−5 2.71953e−8
20241 3.02468e−5 6.47420e−5 2.54232e−9
20760 2.93488e−5 6.02197e−5 2.17732e−8

u通过5e−5门槛,v未通过。v的绝对RMS变化约1.20–1.47e−7,仍超过既定1e−7对应阈值。本包没有证明这是纯FP32噪声,也没有区分更慢收敛或离散波动,因此不能将其改判通过。

末态M=1583.999700639397;初末相对质量偏移1.93463e−7≤1e−3;末4间隔跨度2.97376e−8≤6e−6;每间隔质量变化也通过2e−6。全部流体rho最大偏差2.45519e−4≤.005,实际最大速度.00198440335≤.01。

内部距底8/16/24处实测Σrhov分别.01707495563、.01707951725、.01708397269;相对rho_barQ最大误差.00100084933≤.005,截面跨度相对参照.000528336708≤.002。底/顶宏观质量流量分别.01706953719/.01708357781;底/顶宏观体积流量分别.01706693722/.01708357792。请求、宏观实际流量和population收支分别记录,没有互相替代。

镜像误差:rho偶对称/rho0=4.95464e−7≤2e−5,u奇对称/.002=.000202076431≤.002,v偶对称/.002=.000137883793≤.002。内部中心v符号和非零横向u检查通过。全部rho/u/v节点和各y截面流量保留在results.json。

16步全平面实际收支

审计从20760步末态开始,不用于延长稳态搜索。平均每步:

实际量 数值
底slot population净交换 .01706229161937
底零目标flanks净交换 7.03462865204e−6
顶全平面净交换 −.01708168501500
全边界净交换 −1.23587669805e−5
collision实际舍入 +1.20385084301e−5
全域ΔM −3.20258550346e−7

每步独立ΔM减去边界真实净交换和collision舍入后残差为0;审计版/普通版DDF逐值相同。未扣collision的最大相对物理预算残差1.15158e−8,说明碰撞舍入仍在。压力库下的净排出与正舍入项在该16步窗口大部分抵消;这不证明舍入消失,也不能反推旧J2失败全部由连续模型造成。slot/flanks分账按节点索引,包含斜向分布与时间变化,不直接等同于各段宏观穿壁通量。

实际执行与原始证据

CPU实际命令:

env PYTHONPATH=/home/frank14f/CelerisLab/src PYTHONDONTWRITEBYTECODE=1 PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 /home/frank14f/anaconda3/envs/pycuda_3_10/bin/python - <<'PY' > research/j3-reservoir-2026-10-12/cpu.log 2>&1
from pathlib import Path
import sys, pytest, CelerisLab
from CelerisLab.cuda import compiler_v2 as compiler
root=Path('/home/frank14f/CelerisLab')
assert Path.cwd()==root and sys.executable=='/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python'
assert Path(CelerisLab.__file__).resolve()==root/'src/CelerisLab/__init__.py'
assert Path(compiler.kernel_path('kernel_v2.cu')).resolve()==root/'src/CelerisLab/lbm/kernels/kernel_v2.cu'
print(sys.executable, CelerisLab.__file__, compiler.kernel_path('kernel_v2.cu'))
raise SystemExit(pytest.main(['tests/unit/test_reservoir.py','tests/unit/test_slot_velocity.py','tests/unit/test_planar_velocity.py','tests/unit/test_build_contracts.py','tests/unit/test_state_regressions.py','tests/unit/test_simulation_lifecycle.py','-q','--tb=short','-p','no:cacheprovider']))
PY

GPU前的沙箱nvidia-smi驱动访问失败,原始stderr见gpu-availability-sandbox.log。设备读取的首次自动审批超时,按工具允许仅重试一次成功;不是403,也未更改网络/驱动/环境设置。成功的nvidia-smi -i 0,1在21:35香港时间显示两卡均0%/5MiB,仅Xorg约4MiB,无计算任务。本轮选GPU0,只运行下列科研命令一次:

env CUDA_VISIBLE_DEVICES=0 PYTHONPATH=/home/frank14f/CelerisLab/src PYTHONDONTWRITEBYTECODE=1 PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 /home/frank14f/anaconda3/envs/pycuda_3_10/bin/python tests/validation/run_j3_reservoir.py --output research/j3-reservoir-2026-10-12/results.json --baseline-kernels /tmp/celeris-j3-before/src/CelerisLab/lbm/kernels > research/j3-reservoir-2026-10-12/gpu-validation.log 2>&1

验证器内部再次核对sys.executable、cwd、CelerisLab.__file__与kernel_v2.cu绝对来源。原始CPU成功/GPU失败日志及完整数值结果均保留。不存在JSON序列化失败或物理重跑;未安装依赖。

复核、增量与清理

architecture只读复核未发现公式、符号、时序、静态配置/checkpoint或验证停止条件的阻塞项,未编辑或运行计算。验收依据实际GPU结果,不能由代码复核替代。

incremental.diff相对本轮当前脏树起点:生产5文件+29/−2行,CONFIG说明+20行,测试/验证5文件+222/−11行;共11文件+271/−13行。没有新增生产文件或kernel launch。复用J2场/预算验证,未执行的恢复检查不再计为通过;新模式顶v记录为初猜而非目标。旧物理路径及旧research结果不改。

全部原文件仍在;J1/J2 research材料、四个配置头和notebook与本轮起点哈希一致。git diff --check及增量反向校验通过,反向重建逐字节匹配起点;临时重复src/tests备份在验证后清除,审计构建自动清理。保留所有原始结果和日志。因与旧脏树同文件交叠,没有提交或推送。

本轮停止交复审。后续复跑需要在临时副本中由本包diff反向重建起点CUDA目录,再作为必需baseline传入,不能在当前脏树直接反向应用。未覆盖负例/零幅值/新模式GPU恢复、长期稳定、精度阶、性能、其他支持组合或曲面/AMR;不得把旧J2失败或本J3正例改称通过。