Advanced Topics

The design of SPARC-X-API is schematically shown in the following figure image

Behind the bundle file format

Instead of parsing individual .ion and .inpt files, the bundle format (recognized by ASE by format="sparc") will gather information from all files and check if atomic information and calculation results can be retrieved. The central piece for handling the bundle format is sparc.io.SpardBundle class. You can use it to parse an existing bundle

from sparc.io import SparcBundle
bundle = SparcBundle("path/to/your-calc.sparc", mode="r")
images = bundle.convert_to_ase(index=":")

or write an Atoms object to a bundle with a minimal set of .ion and .inpt files.

from sparc.io import SparcBundle
from ase.io import read
atoms = read("some-externalfile.xyz")
bundle = SparcBundle("path/to/your-calc.sparc", mode="w")
bundle._write_ion_and_inpt(atoms, label="SPARC")

For each individual SPARC file (e.g. .ion, .inpt, .static, .geopt, .aimd), file-specific parsers are in sparc.sparc_parsers.<format> files. Each _read_<format> method will return the structured raw-data dictionary of the files. Similarly, _write_<format> takes the structured dictionary as input and write the file using only relevant data.

Behind the JSON API

The JSON API are directly parsed from the SPARC documentation LaTeX files. The JSON API file (sparc/sparc_json_api/parameters.json) distributed by SPARC-X-API is generated by:

git clone https://github.com/SPARC-X/SPARC.git
python -m sparc.docparser SPARC/doc/.LaTeX

You can use sparc.api.SparcAPI together with the generated JSON API schema:

  1. Load the latest SPARC api

from sparc.api import SparcAPI
sis = SparcAPI()
print(sis.sparc_version)
  1. Check if a variable is available

from sparc.api import SparcAPI
sis = SparcAPI()
# A typo will be detected (actual parameter is CALC_PRESS)
assert "CALC_PRESSURE" not in sis.parameters
  1. Convert string <–> valid value

from sparc.api import SparcAPI
sis = SparcAPI()
latvec = sis.convert_string_to_value("LATVEC", "1.0 0 0\n 0 1.0 0\n 0 0 1.0")
latvec_string = sis.convert_value_to_string("LATVEC", latvec)
  1. Provide help info for a given parameter

from sparc.api import SparcAPI
sis = SparcAPI()

Retriving parameters from old SPARC calculations

sparc.SPARC calculator supports the restart mode which will reconstruct all parameters, psp files and atomic information from an existing SPARC calculation and rerun them.

from sparc import SPARC
calc = SPARC(restart=True, directory="old-calc.sparc")
old_atoms = calc.atoms.copy()
# Redo the calculation with updated parameters
old_atoms.rattle()
calc.set(h=0.2, directory="new-calc.sparc")
old_atoms.calc = calc
old_atoms.get_potential_energy()

Rules for input parameters in sparc.SPARC calculator

When constructing the sparc.SPARC calculator using the syntax

calc = SPARC(directory="", **kwargs)

the parameters are handled in the following priority:

  1. Parameters available to .inpt files (i.e. CAPITALIZED) have highest priority and overwrite all special inputs. They should be set directly using the atomic unit values (i.e the same value as they appear in the .inpt files).

  2. Special inputs (i.e, h, kpts, gpts, xc, convergence) have second highest priority and overwrite default values. They are using the ASE unit system (i.e. Å, eV, GPa, fs).

  3. If none of the parameters are provided, SPARC uses its default parameter set, currently

{"xc": "pbe", "h": 0.25, "kpts": (1, 1, 1)}

We accept parameters in both upper and lower cases, in other words, FD_GRID=[10, 10, 10] and fd_grid=[10, 10, 10] are equivalent. Additionally, boolean inputs (i.e. PRINT_FORCES) can be written in both integer or boolean values.

Multiple occurance of output files

In a typical SPARC calculation, there may be multiple result files in the SPARC bundle, with different suffixes (e.g. .out, .out_01, .out_02 etc.). These files can be a result of restarted geometry optimization / AIMD or written by an ASE optimizer.

When using read_sparc to access the files, you can add include_all_files=True option to parse trajectories from all files.

from sparc.io import read_sparc
# Read all images from .static, .static_01, .static_02 etc.
images = read_sparc("path/to/calc.sparc", index=":", include_all_files=True)

# Read only from .static_02
last_atoms = read_sparc("path/to/calc.sparc", include_all_files=False)

By default, sparc.SPARC calculator only access the last image of last output file when reading the calculation results.