Skip to content

Modify CoherentInterfaceBuilder documentation to clearly state the usage of label_index #4572

@qchempku2017

Description

@qchempku2017

In generating coherent interfaces between film tetragonal TiO2(001) and substrate cubic Si(111), one expect Si(111) to have two inequivalent terminations. These two terminations correspond to 3-coordinated surface and 1-coordinated surface with dangling Si atoms, both with R-3m_1 symmetry.

3-coordinated, shift = 0.375, R-3m_1

Image Image

1-coordinated, shift = 0.875, R-3m_1

Image Image

However, if not supplied with parameter label_index=True, the current implementation in pymatgen.analysis.interface.CoherentInterfaceBuilder.__find_terminations(), can only yield the latter termination ( the 1-coordinated one).

Printing out intermediate values in find_terminations() function further validates this:

        film_slabs = film_sg.get_slabs(ftol=self.termination_ftol, filter_out_sym_slabs=self.filter_out_sym_slabs)
        sub_slabs = sub_sg.get_slabs(ftol=self.termination_ftol, filter_out_sym_slabs=self.filter_out_sym_slabs)
        film_shifts = [slab.shift for slab in film_slabs]

        print("Len(film_slabs):", len(film_slabs))
        print("Len(sub_slabs):", len(sub_slabs))
        if self.label_index:
            film_terminations = [
                label_termination(slab, self.termination_ftol, t_idx) for t_idx, slab in enumerate(film_slabs, start=1)
            ]
        else:
            film_terminations = [label_termination(slab, self.termination_ftol) for slab in film_slabs]
        print("film_terminations:", film_terminations)
        print("film_shifts:", film_shifts)

        sub_shifts = [slab.shift for slab in sub_slabs]
        if self.label_index:
            sub_terminations = [
                label_termination(slab, self.termination_ftol, t_idx) for t_idx, slab in enumerate(sub_slabs, start=1)
            ]
        else:
            sub_terminations = [label_termination(slab, self.termination_ftol) for slab in sub_slabs]
        print("sub_terminations:", sub_terminations)
        print("sub_shifts:", sub_shifts)

...
        print("terminations:", self.terminations)

Output:

Len(film_slabs): 1
Len(sub_slabs): 2
film_terminations: ['TiO2_Cmmm_3']
film_shifts: [0.24999999999999997]
sub_terminations: ['Si_R-3m_1', 'Si_R-3m_1']
sub_shifts: [0.375, 0.875]
terminations: [('TiO2_Cmmm_3', 'Si_R-3m_1')]

This is because when label_index is False, two slabs will first be assigned the same name and then regarded equivalent if they have the same space-group symmetry.

The current documentation sentence falls short of stating this point clearly to the readers, in which one may fail to understand that label_index actually determines the core deduplication behavior, and may have to refer to the source code to figure this out. Without setting label_index=True, physically inequivalent surface terminations sharing the same space-group symmetry may be silently merged, leading to incomplete interface enumeration without any warning.

label_index (bool): If True add an extra index at the beginning of the termination label.

I suggest editing this documentation in the next version, clearly stating how label_index=True correctly captures all inequivalent terminations.

Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions