Add the DFTB+ calculate stage#

calculate is optional. It takes materials that survived screening and runs them through DFTB+ using your own AiiDA installation — MatMelt launches the mydftbp.single WorkChain, waits, and extracts the result. It never ships, installs or imports AiiDA on your behalf.

Prerequisites#

An interpreter with aiida-core, aiida-mydftbp and ase; a working AiiDA profile with its daemon running; and a configured DFTB+ code:

$ verdi profile list
$ verdi code list
$ verdi daemon status

The code’s computer decides where DFTB+ actually runs — that is AiiDA’s job, not a MatMelt backend’s. Do not point this stage at an ssh_exec backend: it only needs to reach the interpreter that talks to your profile, which is normally the local one.

The config block#

stages:
  calculate:
    backend: laptop
    options:
      python: python3
      profile: my-profile
      code_label: dftbplus@cluster
      skf_prefix: /opt/skf/ptbp/complete_set/
      skf_local_path: /home/alice/skf/ptbp/complete_set/
      kpoints: [4, 4, 4]
      max_wallclock_seconds: 3600

code_label and skf_prefix are required; everything else has a default (Configuration reference). Two traps worth naming:

  • skf_prefix is a path on the machine DFTB+ runs on, not on your laptop. It is baked into the generated HSD input.

  • skf_local_path is a path on your machine, used only to create the Slater–Koster node the first time. Omit it and a missing node is a loud failure instead of a silent stall.

Stage order is fixed, so calculate sits between screen and extract wherever you write it in the file.

Check it before running#

$ matmelt doctor

The readiness table gains three rows — the import names differ from the package names, and the fix hint gets them right:

│ calculate │ aiida         │ python3     │ local │ ok      │ aiida importable │
│ calculate │ aiida_mydftbp │ python3     │ local │ MISSING │ ModuleNotFoundE… │
│           │               │             │       │         │ No module named  │
│           │               │             │       │         │ 'aiida_mydftbp'  │
│ calculate │ ase           │ python3     │ local │ ok      │ ase importable   │
└───────────┴───────────────┴─────────────┴───────┴─────────┴──────────────────┘
To fix the missing requirements, run:
  python3 -m pip install aiida-mydftbp

An import probe cannot tell whether your profile works, so doctor also loads the profile and looks the code up for real:

Calculate AiiDA: ok -- AiiDA profile 'Macremote' loads; code
'remote-code@remotecomputer' found

The two failures you are most likely to see, both live:

Calculate AiiDA: PROBLEM -- AiiDA not ready:
aiida.common.exceptions.NotExistent: no Code found with LABEL<dftbplus@cluster>:
No result was found
Calculate AiiDA: PROBLEM -- AiiDA not ready:
aiida.common.exceptions.ProfileConfigurationError: profile `nosuchprofile` does
not exist

A wrong code_label is the commonest setup mistake. Copy it from verdi code list rather than typing it.

Run it#

On already-screened materials, run the one stage:

$ matmelt run --only calculate --yes

--only requires that pipeline.stop_after is not set (they conflict, exit 2). Materials land in CALCULATED; a mid-funnel --only never retires them as DONE, so extract still has work to do:

$ matmelt run --only extract --yes

Or drop --only and let the whole funnel run, in which case new materials flow through calculate on their way to DONE.

To try it on one material first:

$ matmelt run --only calculate --materials Cl1Na1_3D-225 --yes

What happens per material#

The stage’s runner converts relaxed.cif to .gen, generates the DFTB+ HSD input, ensures the Slater–Koster FolderData node exists (finding it by label, or creating it from skf_local_path), submits one mydftbp.single WorkChain, and records the submission before it polls. That ordering is what makes the stage restart-safe: kill MatMelt mid-poll and the WorkChain carries on in your daemon, and the next run re-attaches to it by uuid instead of submitting a second one.

calc_result.json holds the outcome, including every self-healing attempt the plugin made, with absolute SKF paths stripped out. extract folds it verbatim into the final record under _mcli.calculate.

Reading the verdicts#

The plugin’s WorkChain does its own retrying, so its terminal exit statuses are final answers rather than transient errors:

Outcome

MatMelt’s response

Converged

Advance to CALCULATED

Exit 310, 320, 330, 340, 350, 360

Terminal science verdict — FAILED at attempt 1, no retry

Exit 300, 370, unknown, or a broken result file

Retryable fault — spends retry_budget

A material that failed with a terminal status will fail identically if you retry it; one that faulted may not. Diagnose a failed material explains how to tell them apart from status alone.

Note

The doctor output on this page is live, captured against a real AiiDA profile. The end-to-end run results come from the acceptance run recorded in the project’s notes (WorkChain pk 13524, converged at −90.31 eV; the SKF node created once and reused; a SIGKILL mid-poll re-attached by uuid with zero resubmissions), because a working DFTB+ machine is not reproducible while writing docs.