Packaged VASP runners¶
For campaigns that want an ordinary VASP calculation without writing a runner at all.
httk-workflow ships complete VASP runners. A campaign that wants the ordinary
thing — relax a structure, run a single point, or both in sequence — writes no
runner at all: it submits jobs that name one of the installed files in
httk.workflow.vasp.runners.
Their result hooks live in httk.workflow.vasp.collect as
collect_vasp_relax, collect_vasp_static, and collect_vasp_relax_static.
Runner |
Workflow |
Steps |
|---|---|---|
|
|
publish, prepare, run |
|
|
publish, prepare, run |
|
|
publish, prepare, run |
|
|
publish, prepare, promote, run, static |
vasp_relax.sh is the Bash authoring of exactly the same workflow as
vasp_relax.py: the same steps, the same job parameters, the same job state, the same
failure codes, and the same files in the workdir and in the published data. It is
both a working runner and the proof that the two authoring SDKs are one protocol.
Submitting a job¶
Reference a packaged runner as an installed runner, which needs no publication —
the manager resolves the reserved pkg: form inside its own module allowlist, and
httk.workflow is in that allowlist by default:
from httk.workflow import JobSpec, Workspace, prepare_job_payload
from httk.workflow.runners import runner_reference
reference = runner_reference("vasp_relax.py")
job = prepare_job_payload(
"prepared-job",
JobSpec(
name="Relax silicon",
workflow="httk.vasp.relax",
runner_path=str(reference["path"]), # pkg:httk.workflow.vasp.runners/vasp_relax.py
runner_source="installed",
runner_sha256=str(reference["sha256"]),
initial_step="prepare",
data_mode="none",
parameters={"kpoint_density": 30.0, "incar_tags": {"ENCUT": 520}},
),
)
The payload carries the structure and the INCAR it starts from:
mkdir -p prepared-job/files
cp POSCAR INCAR POTCAR prepared-job/files/
httk project init --name workflow .
httk job submit --placement project/si prepared-job
httk workflow manager run
Every httk workflow command names the registered workspace, never a path;
workspace init both creates the workspace and registers the name — see
Project and workflow command line.
The same file can be published to the workspace runner store instead, which pins it by digest for a whole campaign:
workspace = Workspace.initialize("workflow-workspace")
published = workspace.publish_runner("/path/to/vasp_relax.py", name="vasp/relax.py")
The command to run¶
The VASP command is the vasp.command application setting, which the runners
resolve through a.setting("vasp.command") — most
specific first: a job’s own vasp.command parameter, then HTTK_VASP_COMMAND in the
environment, then the workspace’s vasp.command setting, and finally the job’s
legacy vasp_command parameter. The chosen string is split the way a shell would.
Two spellings therefore both work, and mean different things. A machine that invokes VASP its own way still exports the environment variable, and it wins over everything a workspace configures — deployment state a job submitted elsewhere cannot know:
Configure the command once on the workspace, so no one has to export it for every job — and a workspace bound to a remote is even seeded with it from the remote definition when it is created:
httk workspace settings set --key vasp.command --value "srun -n 32 vasp_std" default
httk workflow manager run --pool vasp
The pseudopotential library resolves the same way, as vasp.pseudo_library
(environment HTTK_VASP_PSEUDO_LIBRARY), falling back to the job’s
pseudopotential_library parameter. See Python and Bash authoring parity for the resolution table
and Project and workflow command line for workspace settings.
Declared inputs and parameters¶
The four workflows declare one creation input: structure → files/POSCAR.
Paths are copied verbatim; other objects are serialized with httk.core.save,
which requires the httk-atomistic package for POSCAR/CIF writers.
Every implementation parameter is optional and every one is documented, with its default, in the API
reference of httk.workflow.vasp.runners. The ones a campaign normally sets are
poscar, incar_tags, kpoint_density, pseudopotential_library, timeout, and
collect.
workdir.mode must be persistent (the global default), because the inputs a
remedy rewrites have to be the inputs the next attempt reads. All four packaged
VASP workflows default to data.mode="none": the workdir is the result, no
data/ tree is created, and collection reads the workdir directly.
To also copy the curated outputs into transactional data, opt in explicitly:
httk job new --workflow vasp-relax --input structure=POSCAR --data-mode transactional
The Python equivalent is new_job(..., data_mode="transactional"). This override
wins over the workflow default, and collection supports both modes.
What a run does¶
prepare stages the payload files into the workdir, then derives what the job did
not give: the k-point grid from kpoint_density, EDIFF and EDIFFG from
accuracy_per_atom, MAGMOM from the structure, NBANDS from the POTCAR, and a
POTCAR from pseudopotential_library when none was staged. Explicit incar_tags
are applied first and win over every derived value.
run executes VASP under supervision, writes vasp-run-report.json, and acts on
the classification:
Classification |
What the runner does |
|---|---|
|
records the energy and advances |
anything else with a remedy left |
applies exactly one remedy and asks for another attempt |
anything else without one |
fails with |
Remedies are the bounded ladder of the policy named by remedy_policy, which
defaults to reviewed-v1; they are planned and applied explicitly and never
invented: see Native runner helpers. A group with its own reviewed practice
registers a policy and names it in the job parameters rather than editing a runner. The
ladder position is recorded in the job state directory, so it survives every attempt
of the job, and maximum_remedies bounds how many a single job may apply.
reviewed-v1 handles the edddav_zhegv diagnostic from both EDDAV and
EDDDAV: Call to ZHEGV failed messages. Its CPU MPI recovery first sets
NPAR=1, then increases an explicit NBANDS by two, then gives up. These
are INCAR edits within the existing allocation, not a reduction in MPI ranks.
See the review and limitations.
The publish step leaves outputs in the workdir by default. With transactional
data enabled, it copies the files named by collect into data/, under
data_prefix. This duplicates those files already retained in the workdir.
Relaxation (Python and Bash) collects run/CONTCAR and run/OUTCAR; static
collects run/OUTCAR. The chained workflow archives the relaxation before the
single point overwrites the workdir: it collects the relaxed structure from
run/relax/CONTCAR and the final static energy from run/OUTCAR. With
transactional data, those paths become data/relax/CONTCAR and
data/static/OUTCAR (under data_prefix when supplied). Single-stage
transactional results default to data/vasp/. data_prefix does not change
workdir paths.
No result information is removed by the default change. Custom postprocessing
that hard-codes data/ paths must use the workdir layout or opt into
transactional data. The packaged report and plot scripts support both layouts
and select the final static energy for the chained workflow. The collect
parameter filters transactional copies and the chained relaxation archive; it
does not prune the persistent workdir. Keep that workdir to retain the results.
relaxation-report¶
The packaged vasp-relax, vasp-relax-bash, and vasp-relax-static workflows declare the relaxation-report postprocess script. Run it after collection:
httk workflow postprocess --workspace WS --script relaxation-report
It reads HTTK_WORKFLOW_DATA_DIR (or HTTK_WORKFLOW_WORKDIR when no transactional data directory exists), finds the published OUTCAR and CONTCAR files, and writes relaxation_report.txt and relaxation_report.json into workdir/postprocess/relaxation-report/. Missing files are reported as unavailable and do not make the script fail.
relaxation-plot¶
The same three packaged workflows also declare the relaxation-plot postprocess script. Run it after collection:
httk workflow postprocess --workspace WS --script relaxation-plot
It reads the preferred published OUTCAR from HTTK_WORKFLOW_DATA_DIR (or HTTK_WORKFLOW_WORKDIR when no transactional data directory exists), plots every ionic-step energy, and writes workdir/postprocess/relaxation-plot/relaxation_energies.svg. Missing OUTCAR data or energies are reported and do not make the script fail.
Failure codes¶
Code |
Meaning |
|---|---|
|
no |
|
the structure named by |
|
the chained runner’s relaxation left no CONTCAR |
|
VASP did not complete and no remedy remained |
Formation energies¶
vasp_relax_static.py is the httk v1 formation-energy template without its
database half. A formation energy is assembled from the total energies of several
finished jobs and the elemental references they are compared against, which is an
analysis over jobs rather than a step inside one. What the runner guarantees is the
pair of numbers that assembly needs: one relaxed structure and one total energy of
it, each with the evidence of how it was produced.
Copying one¶
A group whose practice differs from the packaged one should copy the file and edit
it. Each runner is one self-contained file that imports nothing but an installed
httk-workflow, so a copy is a complete runner, publishable as it stands. A group
with its own reviewed remedy practice can also keep the packaged runners and
register its own policy with
httk.workflow.vasp.register_remedy_policy().