C01_gather_3Dxyz Test
测试目标
本页说明 tests/007_gather/C01_gather_3Dxyz 中的参考测试。该测试覆盖
C01_gather_3Dxyz 提供的两个接口:
sub_C01_gather_3Dxyz:把 cell-centered 三维 Cartesian 电磁场Ex,Ey,Ez,Bx,By,Bzgather 到单个粒子位置。sub_C01_gather_3Dxyz_push:在同一个粒子循环中完成 gather、Boris 速度更新和位置推进。
测试重点是局部验证 C01 的三线性插值和 fused gather-push。它回答三个问题:
网格场为三线性解析函数时,C01 是否能精确还原粒子位置处的解析场值?
网格场为光滑但非三线性函数时,网格加密后 gather 误差是否下降?
B=0时,fused gather-push 是否等价于一次解析电场加速?
该测试不是完整 PIC 回路测试;不覆盖 MPI 分解、边界交换、粒子沉积或场推进。
程序结构
source_f90/main.f90构造三组人造场和粒子,调用 C01,并写出 CSV。source_py/analyze.py读取 CSV,独立计算解析参考值,统计误差并生成图片。make.sh使用gfortran -cpp -O2 -fdefault-real-8 -fopenmp编译测试程序。run.sh依次执行清理、编译、Fortran 测试和 Python 后处理。clean.sh删除build/、output/和 Python 缓存。
运行方式
cd tests/007_gather/C01_gather_3Dxyz
bash run.sh
run.sh 会生成 output/*.csv、output/summary.json 和
output/figures/*.png。文档中的静态图是从一次参考运行复制到
docs/source/images/tests/007_gather/C01_gather_3Dxyz 的结果。
输出字段
output/c01_exact.csv:每个粒子的px,py,pz和 C01 gather 得到的Ex,Ey,Ez,Bx,By,Bz。output/c01_convergence.csv:网格数n、网格间距h、物理坐标x,y,z和六个 gather 场分量。output/c01_push.csv:推进前后的粒子位置和速度,即x0,y0,z0,vx0,vy0,vz0与x1,y1,z1,vx1,vy1,vz1。output/summary.json:三个 case 的最大误差、收敛阶和 PASS/FAIL。
坐标约定
C01 内部使用下面的 cell-centered 坐标偏移:
x = par(1,p) + 0.5
y = par(2,p) + 0.5
z = par(3,p) + 0.5
因此 Python 解析参考值也在
\((par_1+0.5, par_2+0.5, par_3+0.5)\) 处计算。这个测试同时检查该
+0.5 坐标约定是否被正确使用。
测试算例
Case |
设置 |
主要检查 |
判据 |
|---|---|---|---|
|
在网格点上填入六个不同的三线性解析场分量,并放置 60 个非整数位置粒子。 |
三线性插值对三线性函数应精确,所以 C01 gather 值应等于粒子位置解析值。 |
最大绝对误差 |
|
使用 |
光滑场不是三线性函数,误差不为零;但网格加密后误差应下降。 |
最小观测收敛阶 |
|
设置 16 个粒子,电场为三线性解析场,磁场设为 |
|
更新后 |
source_py/analyze.py 不调用 C01;它只读取 Fortran 输出并独立计算参考答案。
push case 使用的参考更新为
参考图
exact case 的场值对比。横轴为粒子位置处的解析场分量值,纵轴为
C01 gather 得到的同一分量值。每个点代表一个粒子的一个
Ex/Ey/Ez/Bx/By/Bz 分量;点越贴近虚线,说明 gather 越接近解析值。
convergence case 的误差随网格间距变化。横轴为 h=1/N,纵轴为
gather 场分量相对解析值的误差。L2 汇总所有粒子和六个场分量,
Linf 是最大单分量误差。
push case 的粒子单步位移。每条线段从推进前 (x0,y0) 指向推进后
(x1,y1),用于观察 fused gather-push 的位移方向和量级。
参考运行结果
exact max_abs error : 8.882e-16
convergence min order : 1.936
fused push max_abs error: 2.776e-17
result : PASS
Test Goal
This page documents the reference test under
tests/007_gather/C01_gather_3Dxyz. The test covers two interfaces from
C01_gather_3Dxyz:
sub_C01_gather_3Dxyz: gathers cell-centered 3D Cartesian electromagnetic fieldsEx,Ey,Ez,Bx,By,Bzto one particle.sub_C01_gather_3Dxyz_push: performs gather, Boris velocity update, and position advance in one particle loop.
The test locally verifies C01 trilinear interpolation and fused gather-push.
It checks whether trilinear grid fields are reproduced exactly at particle
positions, whether smooth-field gather errors decrease under refinement,
and whether B=0 fused gather-push matches one analytic electric
acceleration step. It does not test a full PIC loop, MPI decomposition,
boundary exchange, deposition, or field solve.
Program Structure
source_f90/main.f90constructs three synthetic field/particle cases, calls C01, and writes CSV files.source_py/analyze.pyreads the CSV files, computes independent analytic references, computes errors, and saves figures.make.shcompiles withgfortran -cpp -O2 -fdefault-real-8 -fopenmp.run.shperforms cleanup, build, Fortran execution, and Python postprocessing.clean.shremovesbuild/,output/, and Python cache files.
Run Command
cd tests/007_gather/C01_gather_3Dxyz
bash run.sh
run.sh writes output/*.csv, output/summary.json, and
output/figures/*.png. The static figures below are copied from one
reference run into docs/source/images/tests/007_gather/C01_gather_3Dxyz.
Output Fields
output/c01_exact.csv: particlepx,py,pzand gatheredEx,Ey,Ez,Bx,By,Bz.output/c01_convergence.csv: grid sizen, grid spacingh, physical coordinatesx,y,z, and gathered field components.output/c01_push.csv: particle position/velocity before and after the step:x0,y0,z0,vx0,vy0,vz0andx1,y1,z1,vx1,vy1,vz1.output/summary.json: errors, convergence order, and PASS/FAIL for the three cases.
Coordinate Convention
C01 uses the following cell-centered shift:
x = par(1,p) + 0.5
y = par(2,p) + 0.5
z = par(3,p) + 0.5
Therefore Python evaluates references at
\((par_1+0.5, par_2+0.5, par_3+0.5)\). The test also checks that this
+0.5 convention is used consistently.
Test Cases
Case |
Setup |
Main check |
Criterion |
|---|---|---|---|
|
Six different trilinear analytic field components are sampled on grid nodes; 60 particles are placed at non-integer positions. |
Trilinear interpolation should reproduce the analytic value at each particle. |
Max absolute error |
|
Grids |
The field is not trilinear, so the error is nonzero but should decrease under mesh refinement. |
Minimum observed order |
|
16 particles, trilinear electric field, and |
With |
Max absolute error in updated |
source_py/analyze.py does not call C01; it reads Fortran output and
computes independent references. In the push case the reference is
Reference Figures
exact field comparison. x-axis: analytic field component at the
particle. y-axis: the same component gathered by C01. Each point is one
particle-component pair from Ex/Ey/Ez/Bx/By/Bz.
convergence error versus grid spacing. x-axis: h=1/N. y-axis:
error of gathered field components against the analytic field. L2
uses all particles/components; Linf is the largest single component error.
push one-step displacement. Each segment goes from (x0,y0)
before the step to (x1,y1) after the step.
Reference Result
exact max_abs error : 8.882e-16
convergence min order : 1.936
fused push max_abs error: 2.776e-17
result : PASS