Revise and expand the structure mapping functionality

Summary

The structure mapping is reworked for correctness and split into a support package. The supplementary information comes back as a StructureMapping object rather than a dictionary, carrying the relaxation distances, the transformation matrix, any rigid offset that was removed, the ambiguous sites, the warnings, the strain and its separation into a change of volume and a change of shape, and the rotation. It has a string and an HTML representation, as the other classes of this kind do.

An input structure that is rotated or translated relative to the reference structure is now handled. The transformation matrix is searched for where rounding it does not suffice, and the rotation is reported as a disorientation angle and axis reduced over the symmetry of the reference structure.

Defects fixed

Each of these produced a wrong mapping rather than a failure, and each has a regression test that was confirmed to fail against the code as it stood before the fix.

Silent, in that nothing in the result said anything was wrong.

An origin sitting on the other sublattice was never corrected. A rocksalt supercell shifted by half the body diagonal came back with a maximum relaxation distance of 2e-15, no warnings and the same chemical formula, while all sixteen atoms sat on the wrong sites, so a cluster expansion fitted to it was fitted to the anti-site structure.

A slab whose vacuum differed from that of the reference was mapped onto a supercell of twice the size, giving thirty two sites for sixteen atoms.

A slab whose non-periodic cell vector was oblique in a different way from that of the reference was sheared, reporting a maximum relaxation distance of 0.53 Angstrom although its atoms sat on the ideal sites.

A monolayer that had not moved was given a rigid offset of up to 4 Angstrom, purely because its reduced coordinate along the vacuum depends on how much vacuum there is.

A genuine rigid offset was discarded for any structure rattled as much as it was displaced, and for any reference carrying interstitial sites.

Loud, in that the relaxation distances or the warnings gave it away.

Rounding the transformation matrix was preferred to searching for it wherever the result merely satisfied the tolerances, and between roughly twelve and thirty degrees of rotation the rounded matrix is already wrong while still inside them. An exact hexagonal close packed supercell rotated by seventeen degrees came back with a maximum relaxation distance of 1.42 Angstrom and a strain of 0.20.

A valid transformation matrix could be discarded before the criterion that accepts it was ever evaluated, at strains inside the documented tolerance.

A structure with a single vacancy could not be mapped without inert_species, the size of the reference supercell having been rounded down below the number of atoms.

A wire or a molecule was mapped although its cell cannot determine its orientation. Such a structure is now refused.

Breaking changes

All optional arguments of map_structure_to_reference are keyword-only. A call that passed them positionally, such as map_structure_to_reference(s, ref, ['Au']), has to name them instead. This is deliberate: the function takes nine options, and a positional call to it cannot be read.

The second element of the returned tuple is a StructureMapping rather than a dict. It is a read-only mapping, so indexing, get, keys, items, values, len and membership behave as they did, while attributes are the intended form. warnings and ambiguous_sites are tuples rather than lists, so a comparison against [] becomes one against ().

A reference structure has to be periodic along at least two directions. A slab is mapped as before, and a wire or a molecule is refused rather than mapped on terms its cell cannot meet.

calculate_strain_tensor is no longer exported from icet.tools. It computes a property of two cells, has no caller outside this package, and was not part of the documented interface before.

tol_cell has to lie between zero and one, since the bounds of the search scale as 1 / (1 - tol_cell).

For a structure that is not periodic along every direction, volumetric_strain and volume_dilation describe the change of the periodic measure, an area for a slab, rather than of a volume that includes the vacuum.

Testing

The full suite passes with 1172 tests, of which 355 cover the structure mapping. flake8, xdoctest and both the HTML and the doctest build of the documentation are clean.

The tests of the mapping take about three minutes where they took under one before this branch. Two changes account for it, and both buy correctness. Candidates are generated over the whole range the tolerance admits rather than a narrower approximation of it, and distances in reduced coordinates are taken to the closest image, which for an oblique cell the componentwise reduction alone overstates by as much as 73 per cent.

Edited by Paul Erhart

Merge request reports

Loading
Loading