mcpField
P
post-processing

post-processing

github.com/heshamfs数据与数据库83204 次安装1 周前更新
代码仓库

关于 post-processing

面向数值模拟分析的后处理 Skill,指导从模拟输出中提取字段、统计数据、计算派生量并生成报告。它强调先核实文件中的实际字段和网格信息,再开展分析与结果验证。

主要功能

  1. 01提取空间字段与线剖面
  2. 02分析时间序列和统计分布
  3. 03计算梯度、积分等派生量
  4. 04与参考数据比较
  5. 05生成汇总报告
  6. 06验证收敛、守恒与数据有效性

适用场景

  1. 01检查模拟结果中的指定字段
  2. 02判断残差收敛或物理量是否达稳态
  3. 03比较模拟曲线与解析或实验数据
  4. 04整理模拟分析报告

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/heshamfs/materials-simulation-skills --skill post-processing

安装后在 Claude Code 中输入/post-processing确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

CHANGELOG.md
evals/
evals.json
evals/files/
analytical.json
field_output.json
history.json
profile.json
references/
comparison_metrics.md
data_formats.md
derived_quantities_guide.md
statistical_methods.md
scripts/
comparison_tool.py
derived_quantities.py
field_extractor.py
profile_extractor.py
report_generator.py
statistical_analyzer.py
time_series_analyzer.py

详细介绍

后处理技能

分析并提取仿真输出数据中的有效信息。

目标

通过提取字段、统计分析、计算派生量、生成可视化结果以及与参考数据对比,将原始仿真输出转化为可执行的见解。

需收集的输入

运行后处理脚本前,请收集以下信息:

  1. 输出数据位置

    • 仿真输出文件的路径(JSON、CSV、HDF5、VTK)
    • 感兴趣的时间步/快照索引
    • 要提取的字段名称

    请从文件中读取字段名称,切勿自行假设。 提取前,打开输出文件(或运行 field_extractor.py --input <file> --list --json),并且只使用 fields 中实际出现的字段名称。 如果文件中没有 temperature 等字段,请勿自行编造;也不要假设网格大小,应从数据中读取实际的 shape/count。

  2. 分析类型

    • 字段提取(特定时刻的空间数据)
    • 时间序列(量的时间演化)
    • 线剖面(穿过计算域的一维截面)
    • 统计汇总(均值、标准差、分布)
    • 派生量(梯度、积分、通量)
    • 与参考数据对比
  3. 输出要求

    • 输出格式(JSON、CSV、表格)
    • 可视化需求
    • 报告格式

脚本

脚本用途关键输入
field_extractor.py从输出文件中提取字段数据--input、--field、--timestep
time_series_analyzer.py分析时间演化--input、--quantity、--window
profile_extractor.py提取线剖面--input、--field、--start、--end
statistical_analyzer.py计算字段统计信息--input、--field、--region
derived_quantities.py计算派生量--input、--quantity、--params
comparison_tool.py与参考数据进行比较--simulation、--reference、--metric
report_generator.py生成汇总报告--input、--template、--output

工作流

1. 数据清单

首先了解有哪些可用数据:

# List available fields and timesteps
python scripts/field_extractor.py --input results/ --list --json
2. 字段提取

提取特定时间步的空间字段数据:

# Extract concentration field at timestep 100
python scripts/field_extractor.py \
    --input results/field_0100.json \
    --field concentration \
    --json

# Extract multiple fields
python scripts/field_extractor.py \
    --input results/field_0100.json \
    --field "phi,concentration,temperature" \
    --json
3. 时间序列分析

分析各量的时间演化:

# Extract total energy vs time
python scripts/time_series_analyzer.py \
    --input results/history.json \
    --quantity total_energy \
    --json

# Compute moving average with window
python scripts/time_series_analyzer.py \
    --input results/history.json \
    --quantity mass \
    --window 10 \
    --json

# Detect steady state (relative-variation test; best for physical quantities)
python scripts/time_series_analyzer.py \
    --input results/history.json \
    --quantity residual \
    --detect-steady-state \
    --tolerance 1e-6 \
    --json

# Convergence by absolute threshold (physically correct test for residuals)
python scripts/time_series_analyzer.py \
    --input results/history.json \
    --quantity residual \
    --absolute-threshold 1e-6 \
    --json
4. 线剖面提取

提取穿过计算域的一维剖面:

# Extract profile along x-axis at y=0.5
python scripts/profile_extractor.py \
    --input results/field_0100.json \
    --field concentration \
    --start "0,0.5,0" \
    --end "1,0.5,0" \
    --points 100 \
    --json

# Interface profile (through center)
python scripts/profile_extractor.py \
    --input results/field_0100.json \
    --field phi \
    --axis x \
    --slice-position 0.5 \
    --json
5. 统计分析

计算字段数据的统计信息:

# Global statistics
python scripts/statistical_analyzer.py \
    --input results/field_0100.json \
    --field concentration \
    --json

# Statistics in a specific spatial region (1D/2D fields only).
# Coordinates are derived from the field shape and grid spacing
# (explicit dx/dy, or Lx/Ly via dx = Lx/(nx-1)); only the variables
# x, y, z compared against numbers, joined by and/or, are allowed.
python scripts/statistical_analyzer.py \
    --input results/field_0100.json \
    --field phi \
    --region "x>0.3 and x<0.7" \
    --json

# Distribution analysis
python scripts/statistical_analyzer.py \
    --input results/field_0100.json \
    --field phi \
    --histogram \
    --bins 50 \
    --json
6. 派生量

根据原始数据计算物理量:

# Compute interface area
python scripts/derived_quantities.py \
    --input results/field_0100.json \
    --quantity interface_area \
    --threshold 0.5 \
    --json

# Compute gradient magnitude
python scripts/derived_quantities.py \
    --input results/field_0100.json \
    --quantity gradient_magnitude \
    --field phi \
    --json

# Compute volume fractions
python scripts/derived_quantities.py \
    --input results/field_0100.json \
    --quantity volume_fraction \
    --field phi \
    --threshold 0.5 \
    --json

# Compute flux through boundary
python scripts/derived_quantities.py \
    --input results/field_0100.json \
    --quantity boundary_flux \
    --field concentration \
    --boundary "x=0" \
    --json
7. 与参考数据对比

将仿真结果与参考数据进行比较:

# Compare to analytical solution
python scripts/comparison_tool.py \
    --simulation results/profile.json \
    --reference reference/analytical.json \
    --metric l2_error \
    --json

# Compare to experimental data
python scripts/comparison_tool.py \
    --simulation results/history.json \
    --reference experimental_data.csv \
    --metric rmse \
    --interpolate \
    --json

# Compare two simulations
python scripts/comparison_tool.py \
    --simulation results_fine/field.json \
    --reference results_coarse/field.json \
    --metric max_difference \
    --json
8. 生成报告

自动生成报告:

# Generate summary report
python scripts/report_generator.py \
    --input results/ \
    --output report.json \
    --json

# Generate with specific sections
python scripts/report_generator.py \
    --input results/ \
    --sections "summary,statistics,convergence" \
    --output report.json \
    --json

典型后处理流程

完整的仿真分析流程:

python scripts/field_extractor.py --input results/ --list --json                                             # 1. inventory
python scripts/statistical_analyzer.py --input results/field_final.json --field phi --json                    # 2. final-state stats
python scripts/time_series_analyzer.py --input results/history.json --quantity residual --detect-steady-state --json   # 3. convergence
python scripts/derived_quantities.py --input results/field_final.json --quantity volume_fraction --field phi --json    # 4. derived quantities
python scripts/comparison_tool.py --simulation results/profile.json --reference benchmark/expected.json --metric l2_error --json   # 5. compare to reference
python scripts/report_generator.py --input results/ --output analysis_report.json --json                      # 6. summary report

结果解读指南

时间序列分析

根据量的类型,以不同方式解读收敛情况,因为分析器报告的两个信号(convergence.{rate,type} 和 steady_state.reached)回答的是不同问题,二者合理地出现不一致。

残差/误差量(例如 residual、error):

  • 根据绝对值与容差的比较判断收敛:残差低于或等于目标容差(例如 1e-6)即为收敛。使用 --absolute-threshold <tol> 可获取 convergence_threshold 块,这是针对残差在物理上正确的检验方式。
  • 相对的 --detect-steady-state 检验回答的是“残差是否已停止变化?”,而不是“残差是否已收敛?”。对于仍在下降的残差,steady_state.reached = false 是预期结果,并不表示失败。
  • 残差出现平台期意味着求解器停滞(convergence.type = "stalled"),而非达到稳态。
  • 综合判断这些信号:如果 convergence.type 为 fast/linear,且最终残差较小(或 convergence_threshold.reached = true),即使 steady_state.reached = false,也应将本次运行报告为已收敛。

物理量(例如 energy、volume_fraction、mass、interface_area):

  • 能量单调下降:系统正趋近于平衡。
  • 平台期(steady_state.reached = true):已达到稳态。
  • 振荡:可能表示时间步长过大。
  • 突然跳变:可能存在数值不稳定。
统计分析
  • 序参量的双峰分布:两相混合
  • 高方差:微观结构不均匀
  • 偏斜分布:相分数不对称
比较指标
指标解读
L2 误差 < 1%极佳的一致性
L2 误差 1-5%良好的一致性
L2 误差 5-10%中等一致性
L2 误差 > 10%一致性较差,需进一步调查

输出格式

所有脚本都支持 --json 标志,以生成机器可读的输出。大多数脚本会输出一个扁平的顶层对象,其键取决于具体脚本。例如,对单个字段运行 field_extractor.py --include-data 会输出:

{
    "field": "concentration",
    "found": true,
    "data": [[0.1, 0.9], [0.3, 0.6]],
    "shape": [2, 2],
    "min": 0.1,
    "max": 0.9,
    "mean": 0.475,
    "count": 4,
    "source_file": "results/field_0100.json",
    "timestep_info": {"timestep": 100, "time": 1.5}
}

关于封装结构的说明(各脚本的结构并不统一):

  • field_extractor.py、statistical_analyzer.py、time_series_analyzer.py、profile_extractor.py 和 comparison_tool.py 会输出一个扁平对象,其中包含 source_file 键和特定于脚本的结果键。
  • derived_quantities.py 会将其负载封装在 { "inputs": {...}, "results": {...} } 结构中。
  • report_generator.py 会在顶层输出 report_version 和 generator 键,以及所请求的报告部分。

没有脚本会输出顶层的 script、version 或 input_file 键;字段统计信息(min/max/mean/count)位于顶层,而非嵌套在 data 对象下。

验证清单

在信任或报告后处理结果之前,请生成并记录以下具体证据(与此技能的脚本和输出键对应):

  • 先列出实际字段。 运行 field_extractor.py --list --json,并记录实际的 fields 名称和 shape;后续每个 --field 参数都必须出现在该列表中(不得假设存在 temperature,也不得猜测网格大小)。
  • 根据量的类型使用正确的收敛测试。 对于残差/误差,记录通过 --absolute-threshold <tol> 得到的 convergence_threshold.reached 和 final_value(即 |x_final| <= tol 测试),而不是依赖 steady_state.reached;对于物理量,记录通过 --detect-steady-state 得到的 steady_state.{reached,relative_variation,value}。
  • 核对两个收敛信号。 将 convergence.type 和 convergence.rate 与 steady_state.reached 一同记录,并确认 convergence.type = "stalled" 应解读为求解器停滞(而非稳态);残差仍在下降但 steady_state.reached = false 时,不应报告为失败。
  • 根据容差检查守恒性。 记录首个和最后一个时间步的守恒积分(derived_quantities.py --quantity mass / integral,或 volume_fraction),并确认漂移在该动力学的文档所述容差范围内(Cahn-Hilliard 守恒序参量时约为 0;Allen-Cahn 中则预期会变化)。
  • 确认网格间距具有物理意义。 记录 derived_quantities.py 回显的 spacing 块(dx/dy/dz),并验证它来自显式的 dx/dy,或正确的 Lx/(nx-1) 推导;同时确认 stderr 中未输出 WARNING: explicit dx ... inconsistent with Lx。
  • 确认非有限值未破坏结果。 确认派生量脚本未触发 Field contains non-finite value(NaN/Inf),且报告的 min/max 在物理上合理(例如,序参量始终处于预期范围内)。
  • 根据文档所述区间评定比较误差。 记录 comparison_tool.py 的指标值(例如 l2_error),并将其对应到此技能中的一致性区间(<1% 为优秀……>10% 为较差,需调查);同时先确认模拟结果和参考数据已对齐/插值到同一坐标轴上。

常见误区与自我辩解

看似省事的做法为什么不对/应该怎么做
"steady_state.reached = false,所以求解器没有收敛。"相对稳态测试问的是“它是否已停止变化?”,对于仍在下降的残差,答案是否定的。对于残差,请使用 --absolute-threshold <tol> 并读取 convergence_threshold.reached;同时结合 convergence.type/rate 判断。
“残差已趋于平稳,所以它达到了稳态。”残差持平意味着求解器停滞(convergence.type = "stalled",rate > 0.99),而不是收敛。称其已收敛前,请确认平台值确实小于或等于容差。
“我直接提取 temperature/假设网格是 256×256 就行。”字段名称和形状没有保证。请先运行 field_extractor.py --list --json,并且只使用文件实际报告的 fields 和 shape。
“两个网格/两次运行结果一致,所以结果与网格无关。”对两个场使用 comparison_tool.py 只能界定它们之间的差异,不能确定渐近范围。声称结果与网格无关前,请使用 >=3 个分辨率估算观测阶数。
“体积分数看起来稳定,所以质量守恒。”稳定的 volume_fraction(经过阈值处理的计数)并不是守恒积分。请检查首个与最后一个时间步之间 --quantity integral/mass 的漂移是否在容差范围内——并且只有对于守恒的(Cahn-Hilliard)动力学,才应期待漂移约为 0。
“默认的 dx=1.0 足以计算派生量。”如果文件中没有间距信息,脚本会回退到 dx=dy=dz=1.0,因此任何长度/面积/通量/积分的单位都是网格单位,而非物理单位。请提供 --dx/--dy(或在文件中提供 Lx/Ly),并核对回显的 spacing 块。
“程序运行完并输出了 JSON,所以数值有效。”执行完成不代表结果正确。报告前请检查守恒漂移、收敛判定、数值是否有限,以及比较误差范围。

安全性

输入验证
  • 用户提供的字段名称会根据 [a-zA-Z_][a-zA-Z0-9_.-]* 进行验证,以防止通过构造的字段名称进行注入
  • statistical_analyzer.py 会在使用前,根据严格的允许列表验证 --region 条件:只接受坐标变量 x、y、z 与数值字面量进行比较(< <= > >= == !=),并通过 and/or 连接;其他任何内容都会以代码 2 退出。解析后的条件会作为真实的坐标掩码应用(不使用 eval/exec),因此报告的统计数据反映的是请求的区域
  • profile_extractor.py 会根据相同的模式验证字段名称,并将点坐标验证为有限数值,维度最多为 3
  • comparison_tool.py 中的 --metric 值会根据固定的允许列表进行验证(l1_error、l2_error、linf_error、rmse、mae、max_difference、correlation、r_squared);未知指标会返回错误
  • report_generator.py 中的 --sections 会根据已知的节名称进行验证(summary、statistics、convergence、validation、files、parameters、all);未知节会以代码 2 退出
  • --bins(statistical_analyzer)、--points(profile_extractor)和 --window(time_series_analyzer)会被验证为带上限的正整数;超出范围的值会以代码 2 退出
文件访问
  • 所有 JSON 和 CSV 加载函数都会在解析前拒绝超过 500 MB 的文件
  • 加载的 JSON 文件必须以对象(dict)作为根元素
  • report_generator.py 将目录列表限制为最多 10,000 个条目,以防止资源耗尽
  • 脚本会读取用户指定的模拟输出文件(JSON、CSV),但不会遍历明确指定范围之外的目录
  • 除非 Agent 使用 Write 保存报告,否则输出会写入 stdout(JSON)
工具限制
  • Read:用于检查脚本源代码、参考资料和模拟输出文件
  • Write:用于保存分析结果、比较报告或生成的摘要;写入范围仅限用户的工作目录
  • Grep/Glob:用于定位模拟输出文件和搜索参考资料
  • 此技能的 allowed-tools 不包含 Bash,以防 Agent 在处理不可信的模拟输出文件时执行任意命令
安全措施
  • 不使用 eval()、exec() 或动态代码生成——区域解析使用正则表达式匹配,绝不执行代码
  • 所有子进程调用均使用显式参数列表(不使用 shell=True)
  • 缩减工具范围(不包含 Bash)将 Agent 限制为仅执行读写操作
  • 使用前会对字段名称和区域表达式进行清理,以防注入

参考资料

详细信息请参阅:

  • references/data_formats.md - 支持的输入/输出格式
  • references/statistical_methods.md - 统计分析方法
  • references/derived_quantities_guide.md - 物理量计算
  • references/comparison_metrics.md - 误差指标及其解读

要求

  • Python 3.10+
  • NumPy(用于数值运算)
  • 核心功能不依赖其他外部依赖项

版本历史

权威记录请参阅 CHANGELOG.md。

  • v1.1.3 (2026-06-24):新增“验证清单”(基于证据,并与脚本的实际输出键对应:字段列表、残差与物理量的收敛性对比、信号核对、守恒漂移、网格间距合理性、非有限值保护、比较误差区间),并在安全部分之前新增“常见陷阱与合理化说辞”表格。仅更新文档;不改变脚本行为。
  • v1.1.2 (2026-06-23):使评估套件可独立运行且具有区分能力——将真实测试样例复制到 evals/files/(仅包含 phi/concentration 字段,网格为 10x10;残差序列以 5e-6 结束),重写所有评估提示词,使其引用这些确切文件,并新增确定性的 script_checks,用于固定经过验证的脚本输出(包括 1e-6 绝对残差阈值未达到的正确判定)。新增指南,说明应从输出文件读取字段名称,而非自行假设。
  • v1.1.1 (2026-06-23):在 statistical_analyzer.py 中实现了基于实际坐标的 --region 筛选;修复 report_generator.py,使其能够读取嵌套的 fields.*.values 输出;在 derived_quantities.py 的网格间距计算中明确规定 dx/dy/dz 的优先级;新增 --absolute-threshold 收敛模式和关于残差与物理量解读的指南;修正 Output Format 示例和版本元数据;新增 --bins/--window 边界验证。
  • v1.1.0 (2026-03-26):优化描述、评估套件、安全审查,标准化元数据,并新增 CHANGELOG。
  • v1.0.0 (2026-02-25):首次发布。

评论

支持 Markdown