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 Parameters 

57 ---------- 

58 method : {'volume', 'shape'} 

59 'volume' (default) returns the diameter of a sphere with the same 

60 volume as the atoms. 'shape' returns the averaged diameter 

61 calculated from the directions given by the defined surfaces. 

62 """ 

63 

64 if method == 'shape': 

65 cen = self.get_positions().mean(axis=0) 

66 pos = self.get_positions() - cen 

67 d = 0.0 

68 for s in self.surfaces: 

69 n = self.miller_to_direction(s) 

70 r = np.dot(pos, n) 

71 d += r.max() - r.min() 

72 return d / len(self.surfaces) 

73 elif method == 'volume': 

74 V_cell = np.abs(np.linalg.det(self.lattice_basis)) 

75 N_cell = len(self.atomic_basis) 

76 N = len(self) 

77 return 2.0 * (3.0 * N * V_cell / 

78 (4.0 * math.pi * N_cell)) ** (1.0 / 3.0) 

79 else: 

80 return 0.0