How To

Using the CLI interface

This section deals with the usage of the sqsgenerator package. A more granular documentation for the CLI can be found in the CLI Reference.

Once you have managed to install sqsgenerator you should have a command sqsgen available in your shell.

Make sure you can call the sqsgen command before you start, using

sqsgen --version

which should plot version information about sqsgenerator and also its dependencies.

The sqs.json file

sqsgenerator uses a dict-like configuration, to store the parameters used for the optimization process. By default, the program assumes the configuration to be stored in a JSON file named sqs.json in the current directory.

sqsgen run
sqsgen

If you want to use a different file name or path you can always pass it as an argument to the command, e. g.

sqsgen run -i path/to/my/sqs.json
sqsgen -i path/to/my/sqs.json

Simple SQS - an ideal \(\text{Re}_{0.5}\text{W}_{0.5}\) solution

In the following example we use a Monte-Carlo approach using by probing fify million different configurations. Only the first coordination shell should be taken into account. We create super-cell with 54 atoms, by replicating a simple B2 structure

 1{
 2    "structure": {
 3        "lattice": [
 4            [3.165, 0.0, 0.0],
 5            [0.0, 3.165, 0.0],
 6            [0.0, 0.0, 3.165]
 7        ],
 8        "coords": [
 9            [0.0, 0.0, 0.0],
10            [0.5, 0.5, 0.5]
11        ],
12        "species": ["W", "Re"],
13        "supercell": [3, 3, 3]
14    },
15    "iterations": 50000000,
16    "shell_weights": {
17        "1": 1.0
18    },
19    "composition": {
20        "W": 27,
21        "Re": 27
22    },
23    "max_results_per_objective": 10
24}

So let’s go together through this configuration:

  • Lines 4-6: cubic lattice with lattice parameter of \(a_{bcc} = 3.165\;\text{A}\)

  • Lines 9-10: lattice sites at positions \((0,0,0)\) and \((\frac{1}{2}, \frac{1}{2}, \frac{1}{2})\)

  • Line 12: occupy the first site with Tungsten and the second one with Rhenium

  • Line 13: create a \(3 \times 3 \times 3\) supercell

  • Line 15: choose \(5^7\) different configurations randomly

  • Lines 16-18: use only the first coordination shell with a shell weight of \(w_i=1.0\) (4). We have to explicitly state that. By default, SRO parameters in all available coordination shells (3) are minimized at the same time

  • Lines 19-22: distribute 27 Tungsten and 27 Rhenium atoms on the lattice sites. The number of atoms to distribute must match the number of lattice sites to occupy.

  • Line 23: store at most 10 configurations per objective in the output file.

Running an optimization

🚀 Templates

Each of the examples below is packaged into sqsgenerator as a template.

Read more about them in the templates section. To obtain the input file named re-w.first for this example file use:

sqsgen template use re-w.first # re-w.first is the template name
sqsgen template re-w.first # re-w.first is the template name

Run the current example using

sqsgen run -i re-w.first.json
sqsgen -i re-w.first.json

In case you have not passed a custom script the program will create an output file named sqs.mpack. Otherwise, it will modify the passed filename e.g. re-w.first.sqs.json \(\rightarrow\) re-w.first.sqs.mapck.

The sqs.mpack file

The output file sqs.mpack is a binary file in MessagePack format. It contains all the information about the optimization process Those are:

  • input configuration

  • performance metrics

  • all computed structures (in a compressed format)

  • all computed SRO parameters

It holds all results grouped by the value of the objective function \(\mathcal{O}(\sigma)\) (4) in ascending order.

list the output

To view the results of an optimization use (in case you have an sqsgen.mpack file in your current directory):

sqsgen output list
sqsgen output

Similarly, in case our output file is named differently use e.g.

sqsgen output -o re-w.first.sqs.mpack list
sqsgen output -o re-w.first.sqs.mpack

You should see something like

Mode: interact
min(O(σ)): 0.00000
Num. objectives: 5

INDEX  OBJ.     N
0      0.00000  13
1      0.01852  12
2      0.03704  2
3      0.07407  1
4      0.25926  1

To export the first best structure use

sqsgen output structure -f cif
sqsgen output structure -f cif

You should see a file name sqs-0-0.cif. The naming convention is `sqs-{objective_index}-{structure_index}.{format}

In case you want to change the index and want to output the worst structure

sqsgen output structure -f cif --objective 4 --index 0
sqsgen output structure -f cif --objective 4 --index 0
file formats

The native CLI and can export:

  • CIF

  • POSCAR

  • PDB

  • JSON

    • ase

    • pymatgen

    • sqsgen

The python CLI will automatically detect ase and pymatgen in case one or both are installed. To specify a file format use -f {backend}.{format}. E.g. you have pymatgen installed and want to use it as write backend use -f pymatgen.cif. For a full list of available formats use --help switch.

Perform SQS on a sublattice only - \(\text{Ti}\text{N} \rightarrow \text{Ti}_{0.5}(\text{B}_{0.25}\text{N}_{0.25})\)

sqsgenerator allows you to select lattice positions, on which the SQS iteration is then carried out. By specifying the sublattice_mode you can control how the optimization works.

 1{
 2  "iterations": 100000000,
 3  "sublattice_mode": "split",
 4  "structure": {
 5    "file": "ti-n.vasp",
 6    "supercell": [2, 2, 2]
 7  },
 8  "composition": [{
 9    "sites": "N",
10    "B": 16,
11    "N": 16
12  }]
13}
{
  "iterations": 100000000,
  "sublattice_mode": "split",
  "structure": {
    "lattice": [
      [4.253534, 0.0, 0.0],
      [0.0, 4.253534, 0.0],
      [0.0, 0.0, 4.253534]
    ],
    "coords": [
      [0.5, 0.0, 0.0],
      [0.5, 0.5, 0.5],
      [0.0, 0.0, 0.5],
      [0.0, 0.5, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.5, 0.5],
      [0.5, 0.0, 0.5],
      [0.5, 0.5, 0.0]
    ],
    "species": ["Ti", "Ti", "Ti", "Ti", "N", "N", "N", "N"],
    "supercell": [2, 2, 2]
  },
  "composition": [{
    "sites": "N",
    "B": 16,
    "N": 16
  }],
  "max_results_per_objective": 10
}
  • Line 3: sets the sublattice_mode to split. The default is interact.

  • Line 5-6: read the structure from a file named ti-n.vasp and create a \(2 \times 2 \times 2\) supercell

  • Lines 8-12: distribute 16 Boron and 16 Nitrogen atoms on the sites originally occupied by Nitrogen atoms only. The Titanium sublattice remains untouched. Note: the brackets around the composition.

the sublattice_mode parameter

For an in-depth discussion of the different modes please refer to the sublattice_mode section.

  • split: the input structure is splitted into sublattices as defined in the composition The optimization is then carried out on the specified sublattices only. The use cases are:

    • restrict the optimization to a sublattice only (this example)

    • optimize multiple sublattices simultaneously in one run

  • interact: all atoms interact with each other. The SQS optimization is carried out on all atoms. You use this mode if you want to pin certain atoms to position.

In this example this results in N-N, B-N and B-B pairs being optimized whereas. If we had chosen interact mode Ti-Ti, Ti-N and Ti-B would be subject to the optimization as well.

specifying structure files

you can read in structure files using the file key in the structure section.

  • the web version does not support file uploads

  • the native CLI supports only POSCAR and pymatgen JSON and sqsgenerator JSON files

    • the extension determines the file format e.g. ti-n.pymatgen.json or ti-n.sqs.json

  • the python CLI supports all file formats of the native CLI plus what ever ase or pymatgen supports

    • the extension determines the file format and is {backend}.{format}

    • e.g. ti-n.ase.cif (use ase as backend to read a CIF file) or ti-n.pymatgen.cif (use pymatgen as backend to read a CIF file)

    • no backend means sqs

    • to get a list of all available extensions use sqsgen export structure --help

Using Python API

In case you use the Python CLI, you have also might want to use the Python API. The API itself is minimalistic It contains three main functions which can imported from the sqsgenerator package

from sqsgenerator import parse_config, optimize, load_result_pack

parse_config accepts both a JSON string or a dict configuration and returns a config object.

To run an optimization use

from sqsgenerator import parse_config, optimize

with open("re-w.first.json") as f:
    config = parse_config(f.read())

pack = optimize(config)

When specifying a lattice or the coords also numpy arrays are accepted

loading existing results

In case you have an existing sqs.mpack from the webapp or the native CLI file you can load it using load_result_pack:

from sqsgenerator import load_result_pack

with open("sqs.mpack", "rb") as f:
    pack = load_result_pack(f.read())

analysing the results

optimize returns the structures in a packed format. You can think of it as list[tuple[float, list[SqsResult]]] where each entry contains the solutions with the same objective (8) value in ascending order.

To obtain the best structure use

best = pack.best()

while is basically equivalent to pack[0][0]. To see a list of all objectives and the number of structures for each use

for obj, solutions in pack:
    print(f"Objective: {obj}, Num. solutions: {len(solutions)}")

exporting structures

Each solution is of type SqsResult which contains the structure and the computed SRO parameters. You can access the structure structure method. To export all structures you can use (here we choose CIF with pymatgen as backend) the write function:

from sqsgenerator import write

for oi, (obj, solutions) in enumerate(pack):
    for si, solution in enumerate(solutions):
        write(solution.structure(), f"sqs-{oi}-{si}.pymatgen.cif")

Each SqsResult no matter if it is of type SqsResultInteract or SqsResultSplit contains

  • structure method to obtain the structure as a Structure object

  • objective property of the objective value (8) for this structure

  • rank permutation number of species array as a str

analysing SRO parameters

in interact mode

A solution of type SqsResultInteract contains the computed SRO parameters, those can be accessed using the sro method

Assuming our Re-W example from above, you can access the SRO parameters using

solution = pack.best()

sro_params = solution.sro()
"numpy array of shape (num_shells, num_species, num_species) = (1, 2, 2) in this case"

sro_params = solution.sro("Re", "W")
"list containing parameter for each shell (num_shells,) = [α-0-Re-W]"

sro_params = solution.sro("Re", "W")
"same as above, since the SROs are symmetric"

sro_params = solution.sro(74, 75)
"same as above, but uses ordinal numbers of Re and W"

sro_params = solution.sro(1)
"all SRO in shell 1, [α1-74-74, α1-74-75, α1-75-75]"

sro_param = solution.sro(1, "Re", "W")
"single parameter value α1-74-75"

# to convert it to a float use
value = float(sro_param)

in split mode

A solution of type SqsResultSplit contains multiple sublattice results. Each sublattice result is of type SqsResultInteract and can be accessed using the sublattices method .

More examples

High entropy oxide

This example shows how to create a SQS for a high entropy oxide with composition.

It illustrates two different concepts: - distribute vacnancies on a sublattice (here the Oxygen sublattice) - using the split mode to optimize two sublattices (\(\mathrm{Co}\) and \(\mathrm{O}\)) independently

sqsgenerator has a reserved species name 0 (zero) to denote vacancies. In this example we distribute 8 vacancies and 24 Oxygen atoms on the Oxygen sublattice of the \(\mathrm{Co}_3\mathrm{O}_4\) structure.

The input below produces a \(\mathrm{Co}_3\mathrm{O}_4 \rightarrow (\mathrm{Co}_{0.16}\mathrm{Mn}_{0.21}\mathrm{Co}_{0.21}\mathrm{Ni}_{0.21}\mathrm{Fe}_{0.21})\mathrm{O}_{0.75}\) structure.

 1{
 2  "iterations": 1000000,
 3  "sublattice_mode": "split",
 4    "structure": {
 5    "file": "Co3O4.pymatgen.json",
 6  },
 7  "composition": [
 8    {
 9      "sites": "Co",
10      "Cr": 4,
11      "Mn": 5,
12      "Co": 5,
13      "Ni": 5,
14      "Fe": 5
15    },
16    {
17      "sites": "O",
18      "0": 8,
19      "O": 24
20    }
21  ]
22}
 1{
 2  "iterations": 1000000,
 3  "sublattice_mode": "split",
 4  "structure": {
 5    "lattice": [
 6      [8.36, 0.0, 0.0],
 7      [0.0, 8.36, 0.0],
 8      [0.0, 0.0, 8.36]
 9    ],
10    "coords": [
11      [0.25, 0.75, 0.25],
12      [0.00, 0.50, 0.00],
13      [0.25, 0.25, 0.75],
14      [0.00, 0.00, 0.50],
15      [0.75, 0.75, 0.75],
16      [0.50, 0.50, 0.50],
17      [0.75, 0.25, 0.25],
18      [0.50, 0.00, 0.00],
19      [0.375, 0.375, 0.125],
20      [0.375, 0.125, 0.375],
21      [0.625, 0.875, 0.375],
22      [0.125, 0.125, 0.125],
23      [0.375, 0.875, 0.625],
24      [0.375, 0.625, 0.875],
25      [0.625, 0.375, 0.875],
26      [0.125, 0.625, 0.625],
27      [0.875, 0.375, 0.625],
28      [0.875, 0.125, 0.875],
29      [0.125, 0.875, 0.875],
30      [0.625, 0.125, 0.625],
31      [0.875, 0.875, 0.125],
32      [0.875, 0.625, 0.375],
33      [0.125, 0.375, 0.375],
34      [0.625, 0.625, 0.125],
35      [0.861943, 0.361943, 0.861943],
36      [0.888057, 0.111943, 0.111943],
37      [0.111943, 0.111943, 0.888057],
38      [0.111943, 0.888057, 0.111943],
39      [0.138057, 0.138057, 0.361943],
40      [0.138057, 0.361943, 0.138057],
41      [0.388057, 0.888057, 0.388057],
42      [0.361943, 0.138057, 0.138057],
43      [0.861943, 0.861943, 0.361943],
44      [0.888057, 0.611943, 0.611943],
45      [0.111943, 0.611943, 0.388057],
46      [0.111943, 0.388057, 0.611943],
47      [0.138057, 0.638057, 0.861943],
48      [0.138057, 0.861943, 0.638057],
49      [0.388057, 0.388057, 0.888057],
50      [0.361943, 0.638057, 0.638057],
51      [0.361943, 0.361943, 0.361943],
52      [0.388057, 0.111943, 0.611943],
53      [0.611943, 0.111943, 0.388057],
54      [0.611943, 0.888057, 0.611943],
55      [0.638057, 0.138057, 0.861943],
56      [0.638057, 0.361943, 0.638057],
57      [0.888057, 0.888057, 0.888057],
58      [0.861943, 0.138057, 0.638057],
59      [0.361943, 0.861943, 0.861943],
60      [0.388057, 0.611943, 0.111943],
61      [0.611943, 0.611943, 0.888057],
62      [0.611943, 0.388057, 0.111943],
63      [0.638057, 0.638057, 0.361943],
64      [0.638057, 0.861943, 0.138057],
65      [0.888057, 0.388057, 0.388057],
66      [0.861943, 0.638057, 0.138057]
67    ],
68    "species": [
69      27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
70      8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
71    ]
72  },
73  "composition": [
74    {
75      "sites": "Co",
76      "Cr": 4,
77      "Mn": 5,
78      "Co": 5,
79      "Ni": 5,
80      "Fe": 5
81    },
82    {
83      "sites": "O",
84      "0": 8,
85      "O": 24
86    }
87  ]
88}

Templates