pwtools.crys.nearest_neighbors

pwtools.crys.nearest_neighbors(struct, idx=None, skip=None, cutoff=None, num=None, pbc=True, sort=True, fullout=False)[source]

Indices of the nearest neighbor atoms to atom idx, skipping atoms whose symbols are skip.

Parameters:
  • struct (Structure)

  • idx (int) – Atom index of the central atom.

  • skip (str or sequence of strings) – Symbol(s) of the atoms to skip.

  • num (int) – number of requested nearest neighbors

  • cutoff (float) – Cutoff radius in unit defined in struct, e.g. Angstrom. Return all neighbors within that radius. Use either num of cutoff.

  • pbc (bool) – Apply PBC to distances.

  • sort (bool) – Sort nn_idx and nn_dist by distance.

  • fullout (bool) – See below.

Returns:

  • nn_idx (fullout=False)

  • nn_idx,nn_dist (fullout=True)

  • nn_idx (1d array) – Indices into struct.symbols / coords.

  • nn_dist (1d array) – Distances ordered as in nn_idx.

See also

num.match_mask

Notes

num : Depending on struct, there may not be num nearest neighbors, especially if you use skip to leave certain species out. Then the number of returned indices may be less then num.

Ordering : If sort=True, then returnd indices nn_idx and distances nn_dist are sorted small -> high. If sort=False, then they are in the same order as the symbols in struct.symbols. For structs with high symmetry (i.e. bulk crystals) where many nearest neighbors have the same distance from the central atom, the ordering of depends on how numpy.argsort sorts equal values in an array.

Examples

>>> ni=nearest_neighbors(struct, idx=struct.symbols.index('Ca'), num=6, skip='H')
>>> ni=nearest_neighbors(struct, idx=23, cutoff=5.3, skip=['H','Cl'])
>>> # simple rock salt example (used ASE to build dummy struct)
>>> from ase import lattice
>>> at=lattice.bulk('AlN', a=4, crystalstructure='rocksalt')
>>> st=crys.atoms2struct(at); st=crys.scell(st,(2,2,2))
>>> ni,nd=crys.nearest_neighbors(st, idx=0, num=8, fullout=True)
>>> ni
array([ 9, 10, 11, 12, 13, 14,  1,  2])
>>> nd
[ 2. 2. 2. 2. 2. 2. 2.82842712 2.82842712]
>>> # Use `ni` or bool array created from that for indexing
>>> array(st.symbols)[ni]
array(['Al', 'Al', 'N', 'N', 'N', 'N', 'N', 'N'], dtype='|S2')
>>> msk=num.match_mask(arange(st.natoms), ni)
>>> array(st.symbols)[msk]
array(['Al', 'Al', 'N', 'N', 'N', 'N', 'N', 'N'], dtype='|S2')
>>> # If you have many different symbols to skip and you don't want to type
>>> # a longish `skip` list, then use smth like this to include only 'O'
>>> # for example
>>> symbols=['Ca', 'Cl', 'Cl'] + ['O']*10 + ['H']*20
>>> skip=filter(lambda x: x!='O', set(symbols))
>>> ['H', 'Ca', 'Cl']