Convergence Testing
SkillDev toolsBefore production calculations, verify that results are converged with respect to key numerical parameters. The two most important are:
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Convergence Testing skill
About this capability
Use when the user asks to test ENCUT convergence, k-point convergence, or any parameter sweep to determine converged computational settings.
What this skill tells your AI
The instructions your AI receives, as published by hello-qm/catgo-lrg in server/catgo/workflow/skills/analysis/convergence/SKILL.md and read by ahel’s review.
Purpose
Before production calculations, verify that results are converged with respect to key numerical parameters. The two most important are:
- ENCUT (planewave cutoff energy) -- controls basis set completeness
- KPOINTS (k-point mesh density) -- controls Brillouin zone sampling
Convergence is reached when the target property (energy, forces, band gap) changes by less than a threshold (typically 1 meV/atom for energy).
Fan-Out Pattern
Convergence tests use a fan-out DAG: one input structure feeds into
multiple independent single_point calculations with different parameter
values.
+--> single_point(ENCUT=300)
|
structure_input ---+--> single_point(ENCUT=400)
|
+--> single_point(ENCUT=500)
|
+--> single_point(ENCUT=600)
|
+--> single_point(ENCUT=700)
Use single_point (not geo_opt) to isolate the parameter effect without
geometry changes confounding the comparison.
MCP Workflow: ENCUT Convergence
Step 1: Create workflow
{"tool": "catgo_workflow_engine", "arguments": {
"action": "create", "name": "ENCUT convergence - TiO2"
}}
Step 2: Add single_point tasks at each ENCUT
{"tool": "catgo_workflow_engine", "arguments": {
"action": "add_task", "workflow_id": "wf_conv",
"task_type": "single_point",
"params": {"software": "vasp", "ENCUT": 300, "system_name": "ENCUT=300"}
}}
{"tool": "catgo_workflow_engine", "arguments": {
"action": "add_task", "workflow_id": "wf_conv",
"task_type": "single_point",
"params": {"software": "vasp", "ENCUT": 400, "system_name": "ENCUT=400"}
}}
{"tool": "catgo_workflow_engine", "arguments": {
"action": "add_task", "workflow_id": "wf_conv",
"task_type": "single_point",
"params": {"software": "vasp", "ENCUT": 500, "system_name": "ENCUT=500"}
}}
Repeat for ENCUT = 600, 700, 800.
Step 3: Submit
{"tool": "catgo_workflow_engine", "arguments": {
"action": "submit", "workflow_id": "wf_conv"
}}
Step 4: Check results
{"tool": "catgo_workflow_engine", "arguments": {
"action": "get_result", "workflow_id": "wf_conv", "task_id": "task_encut300"
}}
{"tool": "catgo_analyze", "arguments": {
"action": "convergence", "workflow_id": "wf_conv"
}}
MCP Workflow: KPOINTS Convergence
{"tool": "catgo_workflow_engine", "arguments": {
"action": "add_task", "workflow_id": "wf_conv",
"task_type": "single_point",
"params": {"software": "vasp", "ENCUT": 520, "KPOINTS": [2,2,1],
"system_name": "2x2x1"}
}}
{"tool": "catgo_workflow_engine", "arguments": {
"action": "add_task", "workflow_id": "wf_conv",
"task_type": "single_point",
"params": {"software": "vasp", "ENCUT": 520, "KPOINTS": [4,4,1],
"system_name": "4x4x1"}
}}
Repeat for 6x6x1, 8x8x1. Use the converged ENCUT from the previous test.
Python API
ENCUT Convergence
from catgo.workflow import Workflow
wf = Workflow("ENCUT convergence - TiO2")
inp = wf.add_task("structure_input", structure=tio2_json)
encut_values = [300, 400, 500, 600, 700, 800]
tasks = {}
for encut in encut_values:
tasks[encut] = wf.add_task("single_point",
structure=inp.output.structure,
software="vasp", ENCUT=encut,
system_name=f"ENCUT={encut}")
wf.submit()
KPOINTS Convergence
wf = Workflow("KPOINTS convergence - TiO2 slab")
inp = wf.add_task("structure_input", structure=tio2_slab_json)
kpoints_list = [[2,2,1], [4,4,1], [6,6,1], [8,8,1], [10,10,1]]
for kp in kpoints_list:
label = f"{kp[0]}x{kp[1]}x{kp[2]}"
wf.add_task("single_point",
structure=inp.output.structure,
software="vasp", ENCUT=520, KPOINTS=kp,
system_name=label)
wf.submit()
Convergence Criteria
| Property | Threshold | Typical Converged ENCUT |
|---|---|---|
| Total energy | 1 meV/atom | 1.3x max(ENMAX) in POTCAR |
| Forces | 5 meV/A | Same as energy |
| Band gap | 10 meV | May need higher ENCUT |
| Stress tensor | 0.1 kbar | Often needs 1.5x ENMAX |
Recommended ENCUT Values by Element Type
| System | Starting ENCUT Range | Notes |
|---|---|---|
| Simple metals (Cu, Pt) | 300-500 | Usually converges quickly |
| Oxides (TiO2, RuO2) | 400-600 | O has high ENMAX |
| Nitrides, carbides | 400-600 | N, C have moderate ENMAX |
| F-containing | 500-800 | F has very high ENMAX |
Two-Stage Strategy
- ENCUT first: Fix KPOINTS at a moderate value (e.g., 4x4x4), sweep ENCUT. Pick the converged ENCUT.
- KPOINTS second: Fix ENCUT at converged value, sweep KPOINTS. Pick the converged mesh.
This avoids the combinatorial explosion of testing all ENCUT x KPOINTS pairs.
Common Pitfalls
- Always use
single_point, notgeo_opt. Geometry changes at different ENCUT introduce noise that masks the convergence behavior. - For slab models, only converge the in-plane k-points (e.g., NxNx1). The vacuum direction needs only 1 k-point.
- ENCUT should be at least 1.3x the maximum ENMAX in the POTCAR. Check POTCAR ENMAX values before choosing the test range.
- Report energy per atom (E_total / N_atoms), not total energy, for meaningful comparison across different systems.
- Always plot E vs parameter -- convergence should be monotonic. Non-monotonic behavior suggests other issues (e.g., SCF convergence).
Signals
- GitHub stars
- 196
- Forks
- 23
- Last commit
- Sep 2026
Others that do the same job
Advanced
- Catalog kind
- skill
- Gateway key
convergence-test- Source
- github.com/hello-qm/catgo-lrg