Calculating the coordination numbers for different atomic sites

The Structure class of the strct sub-package can be used to determine the coordination number of periodic and non-periodic structures using different methods, all of them described here: doi:10.1021/acs.inorgchem.0c02996.

First, we create an object of the class and import a structure:

[1]:
from aim2dat.strct import Structure

strct = Structure.from_file("files/strct_coord_num/Na2SbCs.xsf", label="Na2SbCs")

Several methods are implemented to calculate the coordination numbers:

  • "minimum_distance": The distance of the closest atom is taken as reference. All atoms inbetween that distance and a relative margin are considered as neighbours of the atomic site. The relative margin can be set via the attribute minimum_distance_delta, the default value is 0.1.

  • "n_nearest_neighbours" defines the number of coordianted sites by the n nearest neighbours via the n_nearest_neighbours parameter.

  • "atomic_radius" takes the sum of radii for each of the corresponding elements and consideres a site as neighbouring if the distance is smaller than the sum. The radius type can be specified via the atomic_radius parameter. The parameter atomic_radius_delta includes a relative tolerance.

  • "econ": The effective coordination number algorithm is an iterative method. Two parameters can be changed to tweak the method: econ_tolerance and econ_conv_threshold with the default values of 0.5 and 0.001, respectively.

  • "voronoi": This method implements various approaches based on a Voronoi tessellation. To obtain, e.g., the method developed by O’Keeffe one can set voronoi_weight_type to rel_solid_angle and the voronoi_weight_threshold to a float number between 0.0 and 1.0.

The coordination numbers for each site can then be readily calculated using the methods calculate_coordination:

[2]:
strct.calculate_coordination()
[2]:
{'distance_avg': {('Cs', 'Na'): 4.048938040566,
  ('Na', 'Sb'): 2.9856709594339996,
  ('Sb', 'Na'): 2.9856709594339996},
 'distance_stdev': {('Cs', 'Na'): 0.0,
  ('Na', 'Sb'): 3.1401849173675503e-16,
  ('Sb', 'Na'): 3.1401849173675503e-16},
 'distance_max': {('Cs', 'Na'): 4.048938040566,
  ('Na', 'Sb'): 2.985670959434,
  ('Sb', 'Na'): 2.985670959434},
 'distance_min': {('Cs', 'Na'): 4.048938040566,
  ('Na', 'Sb'): 2.9856709594339996,
  ('Sb', 'Na'): 2.9856709594339996},
 'nrs_avg': {('Cs', 'Cs'): 0,
  ('Cs', 'Na'): 2,
  ('Cs', 'Sb'): 0,
  ('Na', 'Cs'): 0,
  ('Na', 'Na'): 0,
  ('Na', 'Sb'): 1,
  ('Sb', 'Cs'): 0,
  ('Sb', 'Na'): 2,
  ('Sb', 'Sb'): 0},
 'nrs_stdev': {('Cs', 'Cs'): 0.0,
  ('Cs', 'Na'): 0.0,
  ('Cs', 'Sb'): 0.0,
  ('Na', 'Cs'): 0.0,
  ('Na', 'Na'): 0.0,
  ('Na', 'Sb'): 0.0,
  ('Sb', 'Cs'): 0.0,
  ('Sb', 'Na'): 0.0,
  ('Sb', 'Sb'): 0.0},
 'nrs_max': {('Cs', 'Cs'): 0,
  ('Cs', 'Na'): 2,
  ('Cs', 'Sb'): 0,
  ('Na', 'Cs'): 0,
  ('Na', 'Na'): 0,
  ('Na', 'Sb'): 1,
  ('Sb', 'Cs'): 0,
  ('Sb', 'Na'): 2,
  ('Sb', 'Sb'): 0},
 'nrs_min': {('Cs', 'Cs'): 0,
  ('Cs', 'Na'): 2,
  ('Cs', 'Sb'): 0,
  ('Na', 'Cs'): 0,
  ('Na', 'Na'): 0,
  ('Na', 'Sb'): 1,
  ('Sb', 'Cs'): 0,
  ('Sb', 'Na'): 2,
  ('Sb', 'Sb'): 0},
 'sites': [{'Cs': 0,
   'Na': 2,
   'Sb': 0,
   'element': 'Cs',
   'kind': None,
   'position': [7.034609, 0.0, 0.0],
   'neighbours': [{'element': 'Na',
     'kind': None,
     'site_index': 1,
     'distance': 4.048938040566,
     'position': [2.9856709594339996,
      -2.7858803441915443e-19,
      -1.1238758099096912e-16]},
    {'element': 'Na',
     'kind': None,
     'site_index': 2,
     'distance': 4.048938040566,
     'position': [11.083547040566,
      2.0368784969093668e-16,
      2.706877317564249e-16]}],
   'total_cn': 2,
   'min_dist': 4.048938040566,
   'max_dist': 4.048938040566,
   'avg_dist': 4.048938040566},
  {'Cs': 0,
   'Na': 0,
   'Sb': 1,
   'element': 'Na',
   'kind': None,
   'position': [2.985670959434, 0.0, 0.0],
   'neighbours': [{'element': 'Sb',
     'kind': None,
     'site_index': 3,
     'distance': 2.985670959434,
     'position': [0.0, 2.7858803441915443e-19, 1.1238758099096912e-16]}],
   'total_cn': 1,
   'min_dist': 2.985670959434,
   'max_dist': 2.985670959434,
   'avg_dist': 2.985670959434},
  {'Cs': 0,
   'Na': 0,
   'Sb': 1,
   'element': 'Na',
   'kind': None,
   'position': [11.083547040566, 0.0, 0.0],
   'neighbours': [{'element': 'Sb',
     'kind': None,
     'site_index': 3,
     'distance': 2.9856709594339996,
     'position': [14.069218,
      -2.0368784969093668e-16,
      -2.706877317564249e-16]}],
   'total_cn': 1,
   'min_dist': 2.9856709594339996,
   'max_dist': 2.9856709594339996,
   'avg_dist': 2.9856709594339996},
  {'Cs': 0,
   'Na': 2,
   'Sb': 0,
   'element': 'Sb',
   'kind': None,
   'position': [0.0, 0.0, 0.0],
   'neighbours': [{'element': 'Na',
     'kind': None,
     'site_index': 1,
     'distance': 2.985670959434,
     'position': [2.985670959434,
      -2.7858803441915443e-19,
      -1.1238758099096912e-16]},
    {'element': 'Na',
     'kind': None,
     'site_index': 2,
     'distance': 2.9856709594339996,
     'position': [-2.9856709594339996,
      -1.835675523409463e-17,
      -1.734014780936377e-16]}],
   'total_cn': 2,
   'min_dist': 2.9856709594339996,
   'max_dist': 2.985670959434,
   'avg_dist': 2.9856709594339996}]}

Based on the coordination numbers and distances two atomic sites can be compared using the StructureOperations class:

[3]:
from aim2dat.strct import StructureCollection, StructureOperations

strct_op = StructureOperations(StructureCollection([strct]))
strct_op.compare_sites_via_coordination("Na2SbCs", "Na2SbCs", 1, 2)
[3]:
True