ectoolkits.analysis.rutile110 module#

class ectoolkits.analysis.rutile110.FindSurfaceOadH(atomgroup, Ow_idx, M5c_idx, M='Ti')[source]#

Bases: AnalysisBase

_summary_ Not applicable to Edge models Usage Examples:

1) Flat model: `python atoms = read("init.cif") r110  = Rutile110(atoms, nrow=nrow, bridge_along=bridge_along) Ow_idx, _ = r110.get_wat() Ti5c_idx  = r110.indices["idx_M5c"].flatten() findOH   = FindSurfaceOadH(ag, owidx, cn5idx, nrow=r110.nrow) findOH.run() `

Parameters:

AnalysisBase (_type_) – _description

class ectoolkits.analysis.rutile110.RutileDisDeg(atomgroup, owidx, cn5idx, edge4idx=None, edge5idx=None, nrow=2, M='Ti', bins=500, n_oh=2)[source]#

Bases: AnalysisBase

The new rutile (110)-water interface dissociation degree analysis method

Parameters:

AnalysisBase (MDAnalysis) –

Usage examples: 1) Rutile 110 with <1-11> Edge:

```python from toolkit.structures.rutile110 import Rutile1p11Edge

atoms = read(“init.cif”) r110edge = Rutile1p11Edge(atoms, vecy=vecy, vecz=vecz, cutoff=2.9) owidx, _ = r110edge.get_wat() ind = r110edge.get_indices() ind[‘idx_M5c’][0] = np.flip(ind[‘idx_M5c’][0], axis=1)

cn5idx = ind[‘idx_M5c’].reshape(2, -1) edge5idx = ind[‘idx_edge_M5c’].reshape(2, -1) edge4idx = ind[‘idx_edge_M4c’].reshape(2, -1)

disdeg = RutileDisDeg(ag, owidx, cn5idx, nrow=r110edge.nrow,

edge4idx=edge4idx, edge5idx=edge5idx,)

disdeg.run() ```

  1. Flat model:

    `python atoms = read("init.cif") r110  = Rutile110(atoms, nrow=nrow, bridge_along=bridge_along) owidx, _ = r110.get_wat() cn5idx   = r110.get_indices()['idx_M5c'] disdeg   = RutileDisDeg(ag, owidx, cn5idx, nrow=r110.nrow) disdeg.run() `

static cn2disdeg(cn)[source]#
static dist2cn(dist)[source]#
static dist2histo(dist, bin_edges, nrow)[source]#
get_OH_dist(idx_O, res_dm)[source]#
get_neighbor_oxygen(idx_ti, res_dm, res_idx, n_ow=1)[source]#

Give a group of ti atoms, find their neighboring water oxygen within cutoff rasius self.cutoff. Returns water oxygen indices

Parameters:
  • idx_ti (np.ndarray) – 1-d integer array containing indices for Ti5c atoms.

  • res_dm (np.ndarray) – 2-d distance array containing pair-wise distance between Ti and all water oxygen atoms. This array is prepared in _prepare.

  • n_ow (int, optional) – number of neighboring oxygen for input group of Ti atoms. For example, Ti5c has 1 ad-water; and edge Ti4c has 2 ad-water. Defaults to 1.

Returns:

1-d array containing adsorbed water oxygen indices. If these is no water oxygen within the cutoff raidius, a masking value of ‘-1’ is provided

Return type:

np.ndarray

class ectoolkits.analysis.rutile110.SurfTiOBondLenght(atomgroup, idx_cn5, idx_obr, idx_ow, M='Ti')[source]#

Bases: AnalysisBase

This class calculates the surface TiO bond length.

Parameters:

AnalysisBase (MDA) – MDAnalysis AnalysisBase

Usage example: 1. for flat rutile 110 water interface:

`python atoms = read(os.path.join("init.cif")) r110  = Rutile110(atoms, nrow=nrow, bridge_along=bridge_along) idx_owat, _ = r110.get_wat() ind = inp.r110.get_indices() ind['idx_M5c'][0] = np.flip(ind['idx_M5c'][0], axis=1) ind['idx_Obr'][0] = np.flip(ind['idx_M5c'][0], axis=1) idx_cn5  = ind['idx_M5c'].reshape(2, -1) idx_obr  = ind['idx_Obr'].reshape(2, -1) sbl = SurfTiOBondLenght(ag, idx_cn5, idx_obr, idx_owat) sbl.run() `

get_dTiOad()[source]#
get_dTiObr()[source]#
static pair_TiObr(xyz, idx_obr, idx_ti, box)[source]#
class ectoolkits.analysis.rutile110.WatDensity(atomgroup, M='Ti', rotM=None, dz_bin=0.1, cutoff=2.8)[source]#

Bases: AnalysisBase

MDAnalysis class calculating z-axis averaged water densities

for slab-water interface model. Outputs number densities for both hydrogens and water.

Parameters:

AnalysisBase (object) – MDAnalysis Analysis class base

Usage example: (1) Rutile (110)-water interface with <1-11> edge

```python from toolkit.utils.rutile110 import get_rotM

vecy = np.array([26.34844236, 1.8642182, -2.0615678]) vecz = np.array([0.49339, -0.070221, 9.201458]) rotM = get_rotM(vecy, vecz)

wd = WatDensity(ag, rotM=rotM) wd.run() ```

  1. Flat rutile `python wd = WatDensity(ag, rotM=None) wd.run() `

get_watOidx()[source]#

This methods would select all water oxygen index

Returns:

(<water oxygen index>, <all Hydrogen index>). Note, for rutile-hkl(110) water interface, all hydrogen comes from water.

Return type:

tuple

get_wat_thickness()[source]#
get_z_density(ag)[source]#
static number_density2watdensity(dV)[source]#

dV is the bin volume. Will return a constant converting number density to water mass density. The unit is g cm^{-3}

plot_density_z(oxygen, hydrogen)[source]#
update_pos(ag)[source]#

To avoding collective slab drifting during the simulation. Move atom with index ‘self._idxanchor’ to the same position each frame. Defaults to 1 (One of the slab atom if you are using ase for modle generation).

class ectoolkits.analysis.rutile110.dAdBridge(atomgroup, idx_cn5, idx_obr, idx_owat, idx_adO=None, ref_vec=None, M='Ti', cutoff=2.8)[source]#

Bases: AnalysisBase

MDAnalysis class calculating distances between adsobed water oxygen atoms and two neighboring bridge oxygen atoms. The oxygen water oxygen adsorb on terrace Ti5c atoms. :param AnalysisBase: MDAnalysis Analysis class base :type AnalysisBase: object

Usage example: 1. for flat rutile 110 water interface

`python atoms = read(os.path.join("init.cif")) r110  = Rutile110(atoms, nrow=nrow, bridge_along=bridge_along) idx_owat, _ = r110.get_wat() ind = edge_water.get_indices() # split cn5idx and obr_idx to [<upper idx>, <lower idx>] idx_cn5     = ind['idx_M5c'].reshape(2, -1) idx_obr     = ind['idx_Obr'].reshape(2, -1) _, upper_obr = pair_M5c_n_obr(atoms, idx_cn5[0], idx_obr[0]) _, lower_obr = pair_M5c_n_obr(atoms, idx_cn5[1], idx_obr[1]) idx_obr = np.array([upper_obr, lower_obr]) dab = dAdBridge(ag, idx_cn5, idx_obr, idx_owat, idx_adO=None) dab.run() `

  1. for rutile 110 water interface with edge along <1-11>

    ```python atoms = read(os.path.join(“init.cif”)) vecy = np.array([26.34844236, 1.8642182, -2.0615678]) vecz = np.array([0.49339, -0.070221, 9.201458]) r110edge = Rutile1p11Edge(atoms, vecy=vecy, vecz=vecz, M=”Ti”, nrow=2) ind = r110edge.get_indices() ind[‘idx_M5c’][0] = np.flip(ind[‘idx_M5c’][0], axis=1) idx_cn5 = ind[‘idx_M5c’].reshape(2, -1) idx_obr = np.concatenate([ind[‘idx_Obr’].reshape(2, -1),

    ind[‘idx_hObr_upper’].reshape(2, -1)], axis=1)

    _, upper_obr = pair_M5c_n_obr(atoms, idx_cn5[0], idx_obr[0]) _, lower_obr = pair_M5c_n_obr(atoms, idx_cn5[1], idx_obr[1]) idx_obr = np.array([upper_obr, lower_obr]) dab = dAdBridge(ag, cn5idx, idx_obr) dab.run() ```

get_dab(idx_adO, idx_obr1, idx_obr2)[source]#

get distances between Adsorption water oxygen and Bridge oxygen, aka, dAB.

Parameters:
  • idx_adO (np.ndarray) – indices of ad water oxygen atoms. Use -1 as masking marker, meaning didn’t found Obr whthin cutoff. (see analysis class RutileDisDeg)

  • idx_obr1 (np.ndarray) – indices of row#1 of bridge oxygen atoms.

  • idx_obr2 (np.ndarray) – indices of row#2 of bridge oxygen atoms.

Returns:

(<result distances: Oad-Obr#1>, <result distances: Oad-Obr#2>)

Return type:

tuple (np.ndarray, np.ndarray)

get_neighbor_oxygen(idx_ti, res_dm, n_ow=1)[source]#

Give a group of ti atoms, find their neighboring water oxygen within cutoff rasius self.cutoff. Returns water oxygen indices

Parameters:
  • idx_ti (np.ndarray) – 1-d integer array containing indices for Ti5c atoms.

  • res_dm (np.ndarray) – 2-d distance array containing pair-wise distance between Ti and all water oxygen atoms. This array is prepared in _prepare.

  • n_ow (int, optional) – number of neighboring oxygen for input group of Ti atoms. For example, Ti5c has 1 ad-water; and edge Ti4c has 2 ad-water. Defaults to 1.

Returns:

1-d array containing adsorbed water oxygen indices. If these is no water oxygen within the cutoff raidius, a masking value of ‘-1’ is provided

Return type:

np.ndarray

get_ref(idx1, idx2)[source]#

use minimum image vector between two rows of obr as reference vectors

class ectoolkits.analysis.rutile110.dInterLayer(atomgroup, n_ti5c, dz=0.005)[source]#

Bases: AnalysisBase

MDAnalysis class for interlayer distances calculation. Note that this utility is only good for flat TiO2 (110)-water interface Notice: Because the rotation matrix ‘get_rotM’ method is not very robust, this interlayer distances method is only for flat rutile 110 water interface currently.

Usage example: 1. for flat rutile 110 water interface:

`python atoms  = read(os.path.join("init.cif")) r110   = Rutile110(atoms, nrow=nrow, bridge_along=bridge_along) n_ti5c = r110.get_indices()['idx_M5c'].flatten().shape[0]//2 dil    = dInterLayer(ag, n_ti5c) dil.run() `

static get_n_trilayers(xyz, idx_Ti)[source]#
static get_z_histo(zmean, bin_edges)[source]#
static update_pos(xyz, anchor_pos, anchor_idx)[source]#

To avoding collective slab drifting during the simulation. Move atom with index ‘self._idxanchor’ to the same position each frame. Defaults to 1 (One of the slab atom if you are using ase for modle generation).

class ectoolkits.analysis.rutile110.dObr_NearH(atomgroup, idx_obr, nrow=2, idx_hobr1=None, idx_hobr2=None, idx_eobr=None, M='Ti', bins=500, n_oh=5)[source]#

Bases: AnalysisBase

Distance between Obr and it’s near n_oh proton.

Parameters:

AnalysisBase (MDAnalysis) – MDAnalysis analysis base

Usage example: (1) (110)-water interface with <1-11> edge

```python from toolkit.structures.rutile110 import Rutile1p11Edge

atoms = read(“init.cif”) r110edge = Rutile1p11Edge(atoms, vecy=vecy, vecz=vecz, cutoff=2.9) idx_owat, _ = r110edge.get_wat() ind = r110edge.get_indices() ind[‘idx_Obr’][0] = np.flip(ind[‘idx_Obr’][0], axis=1) idx_obr = ind[‘idx_Obr’].reshape(2, -1) idx_hobr1 = ind[‘idx_hObr_mid’].reshape(2, -1) idx_hobr2 = ind[‘idx_hObr_upper’].reshape(2, -1) idx_eobr = ind[‘idx_edge_O2’].reshape(2, -1) doh = dObr_NearestH(ag, idx_obr, nrow=r110edge.nrow, idx_hobr1=idx_hobr1,

idx_hobr2=idx_hobr2, idx_eobr=idx_eobr)

doh.run() ```

  1. Flat (110)-water interface ```python from toolkit.structures.rutile110 import Rutile110

    atoms = read(“init.cif”) r110 = Rutile110(atoms, nrow=nrow, bridge_along=bridge_along) idx_owat, _ = r110.get_wat() ind = inp.r110.get_indices() ind[‘idx_Obr’][0] = np.flip(ind[‘idx_Obr’][0], axis=1) idx_obr = ind[‘idx_Obr’].reshape(2, -1) doh = dObr_NearestH(ag, idx_obr, nrow=r110.nrow, idx_hobr1=None, idx_hobr2=None, idx_eobr=None) doh.run() ```

static dist2histo(dist, bin_edges, nrow)[source]#
get_OH_dist(obr_indices)[source]#
class ectoolkits.analysis.rutile110.dObr_NearestH(atomgroup, idx_obr, nrow=2, idx_hobr1=None, idx_hobr2=None, idx_eobr=None, M='Ti', bins=500)[source]#

Bases: AnalysisBase

Distance between Obr and it’s nearest proton.

Parameters:

AnalysisBase (MDAnalysis) – MDAnalysis analysis base

Usage example: (1) (110)-water interface with <1-11> edge

```python from toolkit.structures.rutile110 import Rutile1p11Edge

atoms = read(“init.cif”) r110edge = Rutile1p11Edge(atoms, vecy=vecy, vecz=vecz, cutoff=2.9) idx_owat, _ = r110edge.get_wat() ind = r110edge.get_indices() ind[‘idx_Obr’][0] = np.flip(ind[‘idx_Obr’][0], axis=1) idx_obr = ind[‘idx_Obr’].reshape(2, -1) idx_hobr1 = ind[‘idx_hObr_mid’].reshape(2, -1) idx_hobr2 = ind[‘idx_hObr_upper’].reshape(2, -1) idx_eobr = ind[‘idx_edge_O2’].reshape(2, -1) doh = dObr_NearestH(ag, idx_obr, nrow=r110edge.nrow, idx_hobr1=idx_hobr1,

idx_hobr2=idx_hobr2, idx_eobr=idx_eobr)

doh.run() ```

  1. Flat (110)-water interface ```python from toolkit.structures.rutile110 import Rutile110

    atoms = read(“init.cif”) r110 = Rutile110(atoms, nrow=nrow, bridge_along=bridge_along) idx_owat, _ = r110.get_wat() ind = inp.r110.get_indices() ind[‘idx_Obr’][0] = np.flip(ind[‘idx_Obr’][0], axis=1) idx_obr = ind[‘idx_Obr’].reshape(2, -1) doh = dObr_NearestH(ag, idx_obr, nrow=r110.nrow, idx_hobr1=None, idx_hobr2=None, idx_eobr=None) doh.run() ```

static dist2histo(dist, bin_edges, nrow)[source]#
get_min_OH(obr_indices)[source]#
class ectoolkits.analysis.rutile110.staleRutileDisDeg(atomgroup, owidx, cn5idx, edge4idx=None, edge5idx=None, M='Ti', cutoff=2.8)[source]#

Bases: AnalysisBase

MDAnalysis class calculating surface water dissociation degree for rutile hkl(110)-water interface. Besides dissociation, this method will also output surface adsorption water oxygen index, which is useful for TiO2-water interface, because adsorbed water in this system sometimes exchange with sub-interface water.

Parameters:

AnalysisBase (object) – MDAnalysis Analysis class base

Usage example: 1. for rutile 110 (water) interface with <1-11> edge

`python vecy = np.array([26.34844236,  1.8642182,  -2.0615678]) vecz = np.array([0.49339,  -0.070221,  9.201458]) r110edge = Rutile1p11Edge(atoms, vecy=vecy, vecz=vecz, M="Ti", nrow=2) ind = r110edge.get_indices() idx_ow, _ = r110edge.get_wat() ind['idx_M5c'][0] = np.flip(ind['idx_M5c'][0], axis=1) cn5idx = ind['idx_M5c'].reshape(2, -1) edge5idx = ind['idx_edge_M5c'].reshape(2, -1) edge4idx = ind['idx_edge_M4c'].reshape(2, -1) rdd = RutileDisDeg(ag, idx_ow, cn5idx, edge4idx=edge4idx, edge5idx=edge5idx) rdd.run() `

get_neighbor_oxygen(idx_ti, res_dm, n_ow=1)[source]#

Give a group of ti atoms, find their neighboring water oxygen within cutoff rasius self.cutoff. Returns water oxygen indices

Parameters:
  • idx_ti (np.ndarray) – 1-d integer array containing indices for Ti5c atoms.

  • res_dm (np.ndarray) – 2-d distance array containing pair-wise distance between Ti and all water oxygen atoms. This array is prepared in _prepare.

  • n_ow (int, optional) – number of neighboring oxygen for input group of Ti atoms. For example, Ti5c has 1 ad-water; and edge Ti4c has 2 ad-water. Defaults to 1.

Returns:

1-d array containing adsorbed water oxygen indices. If these is no water oxygen within the cutoff raidius, a masking value of ‘-1’ is provided

Return type:

np.ndarray