Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import math
2import numpy as np
4from ase import Atoms
5from ase.cluster.base import ClusterBase
8class Cluster(Atoms, ClusterBase):
9 symmetry = None
10 surfaces = None
11 lattice_basis = None
12 resiproc_basis = None
13 atomic_basis = None
15 def copy(self):
16 cluster = Atoms.copy(self)
17 cluster.symmetry = self.symmetry
18 cluster.surfaces = self.surfaces.copy()
19 cluster.lattice_basis = self.lattice_basis.copy()
20 cluster.atomic_basis = self.atomic_basis.copy()
21 cluster.resiproc_basis = self.resiproc_basis.copy()
22 return cluster
24 def get_surfaces(self):
25 """Returns the miller indexs of the stored surfaces of the cluster."""
26 if self.surfaces is not None:
27 return self.surfaces.copy()
28 else:
29 return None
31 def get_layers(self):
32 """Return number of atomic layers in stored surfaces directions."""
34 layers = []
36 for s in self.surfaces:
37 n = self.miller_to_direction(s)
38 c = self.get_positions().mean(axis=0)
39 r = np.dot(self.get_positions() - c, n).max()
40 d = self.get_layer_distance(s, 2)
41 l = 2 * np.round(r / d).astype(int)
43 ls = np.arange(l - 1, l + 2)
44 ds = np.array([self.get_layer_distance(s, i) for i in ls])
46 mask = (np.abs(ds - r) < 1e-10)
48 layers.append(ls[mask][0])
50 return np.array(layers, int)
52 def get_diameter(self, method='volume'):
53 """Returns an estimate of the cluster diameter based on two different
54 methods.
56 method = 'volume': Returns the diameter of a sphere with the
57 same volume as the atoms. (Default)
59 method = 'shape': Returns the averaged diameter calculated from the
60 directions given by the defined surfaces.
61 """
63 if method == 'shape':
64 cen = self.get_positions().mean(axis=0)
65 pos = self.get_positions() - cen
66 d = 0.0
67 for s in self.surfaces:
68 n = self.miller_to_direction(s)
69 r = np.dot(pos, n)
70 d += r.max() - r.min()
71 return d / len(self.surfaces)
72 elif method == 'volume':
73 V_cell = np.abs(np.linalg.det(self.lattice_basis))
74 N_cell = len(self.atomic_basis)
75 N = len(self)
76 return 2.0 * (3.0 * N * V_cell /
77 (4.0 * math.pi * N_cell)) ** (1.0 / 3.0)
78 else:
79 return 0.0