ectoolkits.utils.rutile110 module#

ectoolkits.utils.rutile110.cellpar2volume(cellpar)[source]#
ectoolkits.utils.rutile110.count_cn(atoms1, atoms2, cutoff_hi, cutoff_lo=None, cell=None, **kwargs)[source]#

count the coordination number(CN) for atoms1 (center atoms), where atoms2 are coordinate atom. This function will calculate CN within range cutoff_lo < d < cutoff_lo, where d is the distance between atoms1 and atoms2. Minimum image convention is applied if cell is not None

Parameters:
  • atoms1 (numpy.ndarray) – Array with shape (N, 3), where N is the number of center atoms. ‘atoms1’ are the position of center atoms.

  • atoms2 (numpy.ndarray) – Array with shape (M, 3), where M is the number of coordination atoms. ‘atoms2’ are the positions of coordination atoms.

  • cutoff_hi (float) – Max cutoff for calculating coordination number.

  • cutoff_lo (float or None, optional) – Min cutoff for calculating coordination number. This function will calculate CN within range cutoff_lo < d < cutoff_lo, where d is the distance between atoms1 and atoms2. Defaults to None.

  • cell (numpy.ndarray, optional) – Array with shape (6,), Array([a, b, c, alpha, beta, gamma]). Simulation cell parameters. If it’s not None, the CN calculation will use minimum image convention. Defaults to None.

Returns:

Array with shape (N,), CN of each atoms atoms1

Return type:

results

ectoolkits.utils.rutile110.d_unique_vecs(vecs)[source]#

get the unique distance vectors

Parameters:

vecs (np.ndarray) – distance vectors

Returns:

a dictionary holds the unique distance vectors.

Return type:

dict

ectoolkits.utils.rutile110.find_cn_idx(atoms1, atoms2, cutoff_hi, cutoff_lo=None, cell=None, **kwargs)[source]#

count the coordination number(CN) for atoms1 (center atoms), where atoms2 are coordinate atom. This function will calculate CN within range cutoff_lo < d < cutoff_lo, where d is the distance between atoms1 and atoms2. Minimum image convention is applied if cell is not None

Parameters:
  • atoms1 (numpy.ndarray) – Array with shape (N, 3), where N is the number of center atoms. ‘atoms1’ are the position of center atoms.

  • atoms2 (numpy.ndarray) – Array with shape (M, 3), where M is the number of coordination atoms. ‘atoms2’ are the positions of coordination atoms.

  • cutoff_hi (float) – Max cutoff for calculating coordination number.

  • cutoff_lo (float or None, optional) – Min cutoff for calculating coordination number. This function will calculate CN within range cutoff_lo < d < cutoff_lo, where d is the distance between atoms1 and atoms2. Defaults to None.

  • cell (numpy.ndarray, optional) – Array with shape (6,), Array([a, b, c, alpha, beta, gamma]). Simulation cell parameters. If it’s not None, the CN calculation will use minimum image convention. Defaults to None.

Returns:

Array with shape (N,), CN of each atoms atoms1

Return type:

results

ectoolkits.utils.rutile110.g_unique_vecs(d: dict)[source]#

ensures the unique vectors calculated by d_unique_vecs.

Handles the case when the each key in the d dictonary has multiple numerically close values. Take the average of these vectors as the “bond” vector.

Parameters:

d (dict) – dictionary calculated from d_unique_vecs

Returns:

a numpy array holds the “bond” vectors. For an octahedral center metal, there are 6 distinct vectors.

Return type:

np.ndarray

ectoolkits.utils.rutile110.get_octahedral_bonds(tio2_cut: Atoms, octahedral_bonds_upper_bound: float = 2.4)[source]#

calculate the octahedral bonds (vectors) in an hkl(1-11) edge model

Parameters:
  • tio2_cut (Atoms) – the edge model cut from the bulk structure. (the output of cut_edge_from_bulk.)

  • octahedral_bonds_upper_bound (float, optional) – The longest length to recogonize an oxygen as a octahedral ligand. Defaults to 2.4.

Returns:

a coordinates array for the octahedral vectors.

Return type:

np.ndarray

ectoolkits.utils.rutile110.get_pair(xyz, idx1, idx2, cutoff_hi, cutoff_lo=None, cell=None, **kwargs)[source]#

search possible pairs between idx1 and idx2, whose distance between are smaller than cutoff_hi

ectoolkits.utils.rutile110.get_rotM(vecy, vecz)[source]#

get the rotation matrix for rotating a rutile model. Specifically, rotating a step edge model s.t x is parrallel to [001], y is parrallel to [1-10], and z is parallel to hkl<110>.

reference:

https://www.cnblogs.com/armme/p/10596697.html#:~:text=旋转坐标系的方法又有两种:%20Proper%20Euler%20angles%2C%20第一次与第三次旋转相同的坐标轴(z-x-z%2Cx-y-x%2C%20y-z-y%2Cz-y-z%2C%20x-z-x%2C,y-x-y)%E3%80%82%20Tait–Bryan%20angles%2C%20依次旋转三个不同的坐标轴(x-y-z%2Cy-z-x%2C%20z-x-y%2Cx-z-y%2C%20z-y-x%2C%20y-x-z); or see https://shorturl.at/pvxyE

Parameters:
  • vecy (numpy.ndarray) – Array with shape (3, ). This direction parallels to Obr/Ti5c direction of the original simulation cell.

  • vecz (numpy.ndarray) – Array with shape (3, ). This direction parallels to the [110] of the original simulation cell.

ectoolkits.utils.rutile110.get_rotM_edged_rutile110(tio2: Atoms, octahedral_bonds_upper_bound: float = 2.4, bridge_along='x')[source]#

compute the unit xyz vectors for a slab of hkl(1-11) edged tio2.

!!!!! TODO —> This method is currently very adhoc and prone to failure !!!!! WE NEED TO IMPROVE THIS

Detailed algorithm: First, one will get all the 6-“octahedral bonds”, (as detailed in get_octahedral_bonds) Second, notice the two of the enlogated octahedral bonds roughly aligns with:

  • unit z direction <the direction of the terminal water -> Ti bond >

  • unit x direction <perpendicular to the bridge water row>

With unit z and unit x, one can reconstruct the unit x by simply cross product

Parameters:
  • tio2_cut (Atoms) – any tio2 hkl(1-11) edge model (hopefully it will work for all input)

  • octahedral_bonds_upper_bound (float, optional) – The longest length to recogonize an oxygen as a octahedral ligand. Defaults to 2.4.

  • bridge_along (str, optional) – The direction of the bridge oxygens, could be either “x” or “y”. Defaults to “y”.

Returns:

the normal vectors, which could be used as the rotM matrix for the coordinates

Return type:

np.array

ectoolkits.utils.rutile110.get_sym_edge(atoms, idx_l_edge4=0)[source]#

Translate the rutile <1-11> edge-water interface model s.t. it looks pretty and symmetric.

The trick is, when using experimental rutile structrue and ase ‘surface’ method generates the edge model, the lower surface 4-coordinated edge Ti has index 1 (0-based). Setting this paticular atom to [0.3, 0.3, 3.5] will get the model look symmetric in the simulation box, thus the model becomes easier to handle. Here symmetric and pretty mean the model looks like:

00*************************** 000************************** ooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooo [110] ooooooooooooooooooooooooooooo ^ ************************000 | o: TiO2 slab ***************************00 | 0: <1-11>-edge *************************** —–> [001] *: water

Parameters:
  • atoms (ase.Atoms) – the edge model ASE atoms.

  • idx_l_edge4 (int, optional) – index of lower surface edge M_4c atom.

Returns:

symmetric & pretty-looking edge model

Return type:

ase.Atoms

ectoolkits.utils.rutile110.get_watOidx(atoms, M='Ti', d_OH_cutoff=1.2, d_MO_cutoff=2.8, cn_M_cutoff=1)[source]#

gets all the water oxygen indices in rutile (110)-water interface

Parameters:
  • atoms (ase.Atoms) – ASE atoms. One snapshot of rutile (110)-water structure.

  • M (str, optional) – The metal atom in rutile structrue. Defaults to “Ti”.

Returns:

0-based indices for water oxygen atoms. watHidx (numpy.ndarray): 0-based indices for water hydrogen atoms. (all the hydrogens)

Return type:

watOidx (numpy.ndarray)

ectoolkits.utils.rutile110.interface_2_slab(atoms, M='Ti')[source]#

transform rutile (110)-water interface model to only the slab, i.e., deleting all the water molecules.

Parameters:
  • atoms (ase.Atoms) – ASE atoms. One snapshot of rutile (110)-water structure.

  • M (str, optional) – The metal atom in rutile structrue. Defaults to “Ti”.

Returns:

The indices for the slab model. atoms_slab(ase.atoms):

Slab model atoms object.

Return type:

idx_slab(numpy.ndarray)

ectoolkits.utils.rutile110.minimize_vectors_triclinic(v: ndarray, box: ndarray)[source]#

computes the mic vector

ectoolkits.utils.rutile110.normalized_vector(v: ndarray)[source]#

calculate the normalized vector

Parameters:

v (np.ndarray) – a vector

Returns:

normalized vector

Return type:

np.ndarray

ectoolkits.utils.rutile110.pair_M5c_n_obr(atoms, idx_cn5, idx_obrs, M='Ti')[source]#

This methods will find the Ti5c’s neighboring Obr atoms.

Parameters:
  • atoms (ASE.Atoms) – ase atoms of your interface model.

  • idx_cn5 (np.ndarray) – 1-d integer array, which contains indices for Ti5c atoms.

  • idx_obrs (np.ndarray) – 1-d integer array, which contains indices for all the Obr atoms.

  • M (str, optional) – Metal elements in the rutile structure. Defaults to “Ti”.

Returns:

(<idx_cn5>, <res_obr>).

Paired Ti5c and Obr indices. Check if they are really paired before you use.

Return type:

tuple

ectoolkits.utils.rutile110.sep_upper_lower(z, indices)[source]#

given indices, seperate them to upper and lower. More specifically, from [<indices>] to [[<idx_upper>], [<idx_lower>]]

Parameters:
  • z (numpy.ndarray) – z coordinates

  • indices (numpy.ndarray) – 0-based indices

Returns:

[[<idx_upper>], [<idx_lower>]]

Return type:

numpy.ndarray