Look at a structure#

MatMelt has no viewer command — it produces CIF files, and you open them in the tool you already use. What it does have is matmelt cif, which exports the DFTB+ relaxed geometry of materials that went through the optional calculate stage.

Export the relaxed structures#

$ matmelt cif --out-dir ./cifs
fetching 1 relaxed geometry from AiiDA...
fetched 1/1 geometry
Run full-remote-run: exported 1 CIF file(s) to ./cifs.

Narrow it with --materials id1,id2 or --materials-file FILE. The store is opened read-only, so this is safe while a run is going on.

Eligible materials are those in CALCULATED, EXTRACTED or DONE with a converged calc_result.json. Anything else is skipped with a counted reason rather than silently omitted. If the config has no calculate stage at all, the command says so instead of producing an empty directory:

cif: this config has no 'calculate' stage, so no material has a DFTB+ relaxed
geometry to export. Add a calculate stage (see 'matmelt init' for a commented
example) and run it first.

Which geometry you get — read this once#

There are three different structures for a material, and they are not interchangeable:

File

What it is

structure.cif

The candidate PyXtal generated

relaxed.cif

After the MACE relaxation in screen

matmelt cif output

After the DFTB+ relaxation in calculate

The DFTB+ geometry is not in calc_result.json: that document stores each healing attempt’s input parameters, so the geometry embedded there is what DFTB+ started from. The relaxed result lives in the final calculation’s retrieved geom.out.gen, which is what this command fetches through AiiDA.

Newer runs cache that geometry into calc_result.json as it completes, so cif serves them straight from disk and spawns no AiiDA process at all when everything is already cached.

What a file looks like#

# Generated by MatMelt -- DFTB+ relaxed geometry, P1 (no symmetry claimed).
data_C1Cl1Cu1Fe1O1_2
_cell_length_a                   4.30012912
_cell_length_b                   3.82865202
_cell_length_c                   4.40788721
_cell_angle_alpha                89.79422523
_cell_angle_beta                 90.45743960
_cell_angle_gamma                120.91417125
_cell_volume                     62.25866186
_symmetry_space_group_name_H-M   'P 1'
_symmetry_Int_Tables_number      1
_chemical_formula_sum            'C Cl Cu Fe O'
_mcli_material_id                'C1Cl1Cu1Fe1O1_2'
_mcli_geometry_source            'geom.out.gen (DFTB+ relaxed)'
_mcli_single_wc_pk               13624
_mcli_calcjob_pk                 13698
_mcli_n_attempts                 5
_mcli_total_energy_eV            -348.42856346
_mcli_band_gap_eV                0.06980000
_mcli_fermi_energy_eV            -3.37417976
_mcli_max_force_eV_Ang           0.00021964

Everything is written as P1: no symmetry is claimed for a relaxed cell, because DFTB+ was free to break it. The _mcli_* items carry the provenance — including the WorkChain and calculation ids, so any number here can be traced back through verdi node show. _mcli_n_attempts 5 means the plugin healed this calculation four times before it converged.

Open it#

$ python3 -c "
from ase.io import read
from ase.visualize import view
view(read('cifs/C1Cl1Cu1Fe1O1_2.cif'))
"

Or open the file directly in VESTA, OVITO or Jmol — it is ordinary CIF. For a quick numerical look without a GUI:

$ python3 -c "
from ase.io import read
a = read('cifs/C1Cl1Cu1Fe1O1_2.cif')
print(a.get_chemical_formula(), a.cell.cellpar().round(4), 'V =', round(a.get_volume(), 4))
"

Structures that never reached calculate#

For candidates from structure or survivors of screen, the CIFs are already in the workspace, one directory per material under run.work_dir — structure.cif and relaxed.cif. No export step is involved; open them the same way.

Script it#

$ matmelt cif --out-dir ./cifs --json
{
  "run": "full-remote-run",
  "out_dir": "./cifs",
  "written": [
    {"id": "C1Cl1Cu1Fe1O1_2", "path": "./cifs/C1Cl1Cu1Fe1O1_2.cif",
     "wc_pk": 13624, "calc_pk": 13698}
  ],
  "skipped": [], "failed": [], "notes": [], "unmatched": []
}

Progress and warnings go to stderr, so stdout stays parseable. skipped, failed and unmatched are counted rather than silent: a material you asked for and did not get is always accounted for somewhere.