Hide keyboard shortcuts

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 

3 

4from ase import Atoms 

5from ase.cluster.base import ClusterBase 

6 

7 

8class Cluster(Atoms, ClusterBase): 

9 symmetry = None 

10 surfaces = None 

11 lattice_basis = None 

12 resiproc_basis = None 

13 atomic_basis = None 

14 

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 

23 

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 

30 

31 def get_layers(self): 

32 """Return number of atomic layers in stored surfaces directions.""" 

33 

34 layers = [] 

35 

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) 

42 

43 ls = np.arange(l - 1, l + 2) 

44 ds = np.array([self.get_layer_distance(s, i) for i in ls]) 

45 

46 mask = (np.abs(ds - r) < 1e-10) 

47 

48 layers.append(ls[mask][0]) 

49 

50 return np.array(layers, int) 

51 

52 def get_diameter(self, method='volume'): 

53 """Returns an estimate of the cluster diameter based on two different 

54 methods. 

55 

56 method = 'volume': Returns the diameter of a sphere with the 

57 same volume as the atoms. (Default) 

58  

59 method = 'shape': Returns the averaged diameter calculated from the 

60 directions given by the defined surfaces. 

61 """ 

62 

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