A cluster vector calculation requires all atoms to reside on a fixed
lattice. Properties of interest, on the other hand, are typically
calculated for a structure in which cell metric and atoms have
been allowed to relax. Unless the ideal structures have been saved prior to
relaxation, one is therefore faced with the task of mapping back the relaxed
structure onto the ideal one. In some cases, in particular involving vacancies,
relaxation can also lead to atoms moving between sites, in which case
remapping is mandatory.

This is the purpose of the function
map_structure_to_reference(). The
function is also useful to analyze whether the relaxation has gone too
far for the cluster expansion to be viable, i.e., whether the ideal
structure from which the relaxation started is not a valid
representation of the structure for which the property has been
obtained.

First, for the sake of demonstration, a reference structure defining
the ideal lattice is created, and a supercell thereof is scaled and
rattled to simulate relaxation in an energy minimixation.

reference=bulk('Au',a=4.00)supercell=reference.repeat(3)supercell.rattle(0.1)supercell.set_cell(1.05*supercell.cell,scale_atoms=True)# Switch some atoms to Pdforiin[0,1,5,8,10]:supercell[i].symbol='Pd'

The structure can now be mapped onto a structure in which all atoms reside
on ideal lattice sites. The function returns the ideal structure, as well as
the maximum and average displacement.

tolerance=0.8# Tolerance in Angstrom for how far# the atoms are allowed to have been displaceedideal_structure,r_max,r_av=map_structure_to_reference(supercell,reference,tolerance)print('Maximum displacement: {:.3f} Angstrom'.format(r_max))print('Average displacement: {:.3f} Angstrom'.format(r_av))

If the structure to be mapped contains vacancies additional keywords
should e provided, (1) vacancy_type, the chemical symbol that
signifies vacancies in the reference structure, and (2)
inert_species, a list of elements that are never substituted for a
vacancy. The latter allows the code to rescale the volume of the cell
and can be omitted, but the mapping is then more likely to fail.

In the example below, a Au-Pd-H-vacancy system is created. In this
example, vanadium ('V') represents vacancies. The system of choice
consists of two sublattices, one occupied by Au and Pd and another
occupied by H and vacancies. Since Au and Pd belong to a sublattice
in which we do not allow vacancies, we may set inert_species=['Au','Pd'].

The complete source code is available in
examples/map_structure_to_reference.py

"""This example demonstrates how to map a structure in which the cell hasbeen scaled and/or the atoms displaced onto an ideal (primitive) structure"""# Import modulesfromicet.toolsimportmap_structure_to_referencefromase.buildimportbulkfromaseimportAtom# End import# Begin by creating a reference structure, in this case fcc Au.# Then create a supercell structure, scale the cell and displace the atoms to# simulate a relaxed structure.reference=bulk('Au',a=4.00)supercell=reference.repeat(3)supercell.rattle(0.1)supercell.set_cell(1.05*supercell.cell,scale_atoms=True)# Switch some atoms to Pdforiin[0,1,5,8,10]:supercell[i].symbol='Pd'# Map the "relaxed" structure onto an ideal supercelltolerance=0.8# Tolerance in Angstrom for how far# the atoms are allowed to have been displaceedideal_structure,r_max,r_av=map_structure_to_reference(supercell,reference,tolerance)print('Maximum displacement: {:.3f} Angstrom'.format(r_max))print('Average displacement: {:.3f} Angstrom'.format(r_av))# Map a structure that contains vacancies, in this case Pd-Au-H-Vac, in which# Pd and Au share one sublattice and Pd and H another.reference=bulk('Au',a=4.00)reference.append(Atom(('H'),(2.0,2.0,2.0)))supercell=reference.repeat(3)supercell.rattle(0.1)supercell.set_cell(1.05*supercell.cell,scale_atoms=True)# Switch some Au to Pd and delete some H (to create vacancies)foriin[0,4,6,2,7,3,17]:ifsupercell[i].symbol=='Au':supercell[i].symbol='Pd'elifsupercell[i].symbol=='H':delsupercell[i]tolerance=0.8ideal_structure,r_max,r_av= \
map_structure_to_reference(supercell,reference,tolerance,vacancy_type='V',inert_species=['Au','Pd'])print('Maximum displacement: {:.3f} Angstrom'.format(r_max))print('Average displacement: {:.3f} Angstrom'.format(r_av))