13 KiB
J2 静态有限平壁 slot:运行前冻结约定
2026-10-12。root唯一写入,沿用J1能力范围。起点HEAD和208个现有文件的准确SHA256见baseline.json;src/tests副本仅为制作本包增量和旧路径对照。保留此前脏树、checkpoint v3、四个配置头和notebook。不提交推送,不修改其他项目或环境。
参考和修改范围(代码修改前记录)
沿用本地lbm-ref-architecture-guard。已搜索并核对ref/OpenLB/src/boundary/zouHeDynamics.hh:67–118,以及research/design-2026-10-09/jet-study.md中Zou–He Eq14–18、Ho scheme A的本地阅读记录。
- 只重建poststream未知populations;已有paired-D2Q9 helper负责对应方向、密度分母和切向矩修正,不改公式。
- reconstruction后在同一节点collision/store。slot与零速flanks共用y=1物理平面,均不额外halfway反射。
- 空间目标profile只改变传给helper的局部速度,不改变分布阶段或引入launch。静态幅值不需要时间插值。
- profile与离散求和是本包公开的设计约定,不声称由参考文献证明其数值精度;实际流量、对称与收支须实测。
修改范围:config参数/宏/静态签名→compiler生成临时头→planar_velocity目标函数→现有init/step;checkpoint仅增加静态宽度比较(旧v3缺省为0);CONFIG说明、针对性单测和复用J1审计的J2验证器。没有注册框架或新生产kernel。
参数、符号与初始化
新增整数method.wall_slot_width=W,默认0保留J1整平面路径;非零时要求2≤W≤NX、on_site_velocity且physics.velocity=0。中心c=(NX−1)/2,x=0..NX−1,单元面积权重均为1。
有限宽W<NX时s=2(x−c)/W,w(x)=(1−s²)²(|s|<1),其余为0。底部Cartesian v_b=Aw,A=wall_normal_velocity是连续profile中心峰值,离散中心不一定取到A,不重新归一峰值。公开请求Q=AΣ_x w(x),上部Cartesian v_t=Q/NX。W=NX明确使用w=1而不是保留边缘shape;W=0仍是J1的均匀A。CPU双精度求和生成top速度宏,实际CUDA目标为FP32,容许对应舍入;这只是请求体积配平,不是实际密度加权质量精确配平。
正A:底部向流体法向+n_y注入,上壁向流体法向−n_y故排出;负A两端反转。平面y=1与NY−2,H=NY−3。有限slot初态rho=1、u=0,v在底部profile与均匀top之间按y/H线性插值,写局部feq作为g(0);初态满足目标但不是已求得的稳态/散度自由场。之后pull g(t)→到达时刻f(t+dt)→未知重建→SRT→g(t+dt)。全宽/禁用沿原J1初始化。
冻结有界验收(首次测试前)
- NX48,NY35,H32,nu=.1,U=0,rho0=1。有限宽W16,A=0,+.002,−.002;峰值尺度Re=A_abs*H/nu=.64,Ma≈.00347。不做端点或网格sweep。
- 采样间隔519步,每例最多40间隔=20760步,至少8间隔后才判稳。连续4间隔完整u/v场各自RMS变化/速度尺度≤5e−5;速度尺度固定max(|A|,.002),不是用近零观测值作分母。每间隔相对初始质量变化≤2e−6,最后4间隔质量相对跨度≤6e−6,初末相对质量偏移≤1e−3。记录完整历史,不将持续增长解释为gauge freedom。
- 所有populations有限,rho最大偏离1≤.005,实际最大速度≤.01。零幅值时所有流体节点最大速度≤2e−6。
- 有限正/负:内部距离底平面8、16、24处实测Σrhov,对rho_barQ的相对误差≤.005,三个截面流量跨度/|rho_barQ|≤.002;这是带弱可压缩/离散误差的诊断参照,不以请求量自证。另记录所有边界和内部宏观体积流量Σv、质量流量Σrhov。底部/上部宏观目标最大速度误差≤2e−6。
- x镜像x↔NX−1−x:rho、v偶对称,u奇对称。max|rho−mirror(rho)|/rho0≤2e−5;max|v−mirror(v)|/速度尺度、max|u+mirror(u)|/速度尺度≤.002。容差为FP32温和低速案例诊断值,不宣称误差阶。实际内部中心v须与A同号,且max|u|>1e−5,防止只有均匀伪解通过流量。
- 全宽W=NX、A=.002:同网格/U=0/初值,与本包起点原J1均匀路径比较初始化和64步DDF/flags逐值相同。默认关闭的旧bounce_back短通道也与起点逐值相同。
- 每例再核对16步实际全平面population预算:包含全部底部slot、零目标flanks和整个上壁的真实incoming/outgoing;独立记录实际collision舍入。预算残差/M≤2e−7,另报不扣collision的物理残差;审计版与普通版逐值相同。必要时复用J1测试审计并细分slot/flank账,生产不加记录器。
- 配置错误、静态参数改变、checkpoint宽度/幅值不一致必须在写状态前拒绝;同参数slot恢复后续短轨迹逐值相同;兼容旧v3缺少宽度字段时默认0。实际profile节点值/请求Q独立验算(CPUshim与GPU场),保持已有J1矩测试。
全部运行固定cwd=/home/frank14f/CelerisLab、解释器=/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python、进程PYTHONPATH=/home/frank14f/CelerisLab/src。每次Python/编译/测试核对来源;每次GPU执行先查获准GPU0/1空闲。原始失败/成功日志保留;门槛变动必须显式记录。当前尚未执行本包测试。
完成状态:实现完成,有限 slot 未通过质量稳态验收
以上为运行前冻结记录。门槛未改,未追加长期计算或更换参数以求通过。正/负有限slot均达到20760步上限,末段速度变化达标,但质量仍增长;不能称为稳态质量验收通过,也不能以压力基准自由度接受。生产模式默认关闭,CONFIG中已标注本轮实测限制。
| 案例 | 步数 | 质量相对初态偏移 | 末4间隔质量相对跨度 | 内部质量流量最大相对误差 | 判定 |
|---|---|---|---|---|---|
| A=0,W16 | 4152 | 6.70552e-8 | 0 | 内部实测0 | 通过 |
| A=+.002,W16 | 20760 | 9.44271e-5 | 9.10981e-6 | 2.41774e-4 | 质量/稳态失败 |
| A=−.002,W16 | 20760 | 8.50923e-5 | 8.50902e-6 | 3.34474e-4 | 质量/稳态失败 |
有限案例末4间隔的质量增量分别约2.18–2.33e-6与2.01–2.20e-6/间隔,超过2e-6;窗口跨度超过6e-6。总偏移仍小于1e-3,不能用这一点替代末段漂移门槛。零幅值最终整个流体域u=v=0。
请求与真实流量
W16、NX48时Σw=8.533447265625,Q=±0.01706689453125,top v=±0.000355560302734375。离散峰值略小于A。原始实际rho/u/v二维场、全部纵向截面的宏观Σv和Σrho*v、质量采样与真实population账均见results.json。
| A | 内部y距8处Σrho*v | 距16处 | 距24处 | 底平面Σrho*v | 顶平面Σrho*v |
|---|---|---|---|---|---|
| +.002 | .01706983335 | .01707181893 | .01707263291 | .01707108133 | .01706793159 |
| −.002 | −.01706487872 | −.01706400141 | −.01706263795 | −.01706563681 | −.01706770062 |
内部截面跨度相对参照为1.64019e-4和1.31282e-4,均通过.002门槛。边界最大速度误差为3.59193e-8和3.30522e-8;最大实际速度约.0019844,密度最大偏差分别3.41552e-4和2.47041e-4。
对称与独立质量预算
rho偶对称误差/rho0:正5.01052e-7、负4.99189e-7。u奇对称误差/固定.002:正9.03279e-5、负9.03303e-5;v偶对称误差/固定.002:正1.00537e-4、负9.03337e-5。均低于冻结门槛。内部中心v方向和非零横向u检查通过。
每例末态16步的实际全平面预算残差均为0,审计版与普通版逐值相同。这只证明已记录FP32分布的离散收支相符,不代表质量恒定或物理误差为0。
| A | 每步平均ΔM | 全边界平均净流入 | 平均collision舍入 |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| +.002 | 8.10414e-6 | 3.89630e-6 | 4.20783e-6 |
| −.002 | 6.77782e-6 | 2.62831e-6 | 4.14951e-6 |
未扣collision的最大相对物理预算残差为正4.94425e-9、负8.18954e-9。正case底slot/flanks/top平均净交换为.01706407918、7.56886e-6、−.01706775173;负case为−.01705836912、−7.00448e-6、.01706800191。完整incoming/outgoing均已存储,没有忽略零目标flanks。这种按节点索引的population分账包括时间变化和斜向分布重分配,flanks分账净值不能直接解释为该处宏观穿壁速度。
结论限于实测:请求体积配平没有给出实际质量精确配平,且FP32碰撞舍入也贡献了增长。只读复核未发现本包profile、Zou–He未知方向、符号、阶段或checkpoint方面的必改编码错误。若后续要改变质量控制/出口条件,应先重新明确物理契约;本包未加入动态top、质量修正或密度钳制。
回归与只读复核
- CPU:98 passed、13 subtests passed,4.34秒,见cpu.log。包括实际CUDA helper CPUshim的9种profile/幅值组合、离散Q、配置/静态签名、checkpoint宽度不一致在写状态前拒绝、旧v3缺宽度按0、同宽度恢复,以及已有J1矩/力/对象限制与状态测试。
- 全宽W48与起点原J1 W0,U0=0/A=.002,初态与64步DDF/flags逐值相同。默认关闭旧通道7步DDF/flags与起点逐值相同。
- 正slot checkpoint载入新Simulation后7步DDF/flags/step_count逐值相同。
- architecture只读复核:未发现生产编码必改项;发现验证器原先允许省略baseline使两项比较跳过。现已要求该参数,并用CLI检查确认省略时在访问CUDA前退出2。本次GPU调用始终带baseline,因此不影响数值结果;未重跑物理路径。
- 本轮最终数值验证进程退出1,真实反映两例失败,不报告成全通过。
实际执行与失败记录
首次沙箱内nvidia-smi无法连接驱动;获准设备访问后只读检查成功:GPU0为0%、9MiB且无计算进程,GPU1已有其他Python进程占约362MiB。每次GPU运行前重复核对,只用物理GPU0;未干扰GPU1。未安装依赖或修改环境设置。
CPU实际命令(cwd固定为本项目):
env PYTHONPATH=/home/frank14f/CelerisLab/src PYTHONDONTWRITEBYTECODE=1 PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 /home/frank14f/anaconda3/envs/pycuda_3_10/bin/python - <<'PY' > research/j2-slot-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
assert 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_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
数值验证实际命令(执行两次;两次前均核对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_j2_slot.py --output research/j2-slot-2026-10-12/results.json --baseline-kernels /tmp/celeris-j2-before/src/CelerisLab/lbm/kernels > research/j2-slot-2026-10-12/gpu-validation.log 2>&1
第一次在零幅值计算完成后,输出JSON时因NumPy bool失败,日志原样移为gpu-serialization-failure.log;没有生成完整结果。将checks显式转为Python bool后完整重跑,模型/参数/门槛未改。第二次数值失败记录保留为gpu-validation.log,逐项指标在results.json。
CLI缺baseline检查使用同一解释器/进程PYTHONPATH和来源断言,通过runpy运行run_j2_slot.py,argv为['run_j2_slot.py','--output','unused.json'],断言SystemExit.code==2;原始stderr与确认在cli.log。未访问GPU、未创建unused.json。
增量与保存
incremental.diff仅包含相对本包起点的12个文件:生产代码6个文件+43/−3行,CONFIG说明+29/−2行,测试与验证5个文件+256/−6行,总计+328/−11行。没有新增生产文件或kernel launch。为避免混入此前同文件中的修改,不提交;没有推送。四个配置头和notebook的SHA256与起点相同,其余原文件均保留。git diff --check和增量补丁反向校验通过,反向应用后逐字节匹配起点哈希。
保留全部原始成功/失败日志。临时CUDA审计构建自动清理,重复起点副本在补丁反向核验后删除。日后复跑需先在临时副本中用本包diff反向重建起点src,再提供其kernels目录作为必需的baseline;不要在当前脏工作树直接反向应用。停在此包交复审;尚未覆盖长期质量稳定、端点/网格阶/性能、其他碰撞/精度/streaming、曲面slot或AMR。