r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1import numpy as np

3from ase import Atoms

4from ase.cluster.util import get_element_info

7def Icosahedron(symbol, noshells, latticeconstant=None):

8 """

9 Returns a cluster with the icosahedra symmetry.

11 Parameters

12 ----------

13 symbol : str or int

14 The chemical symbol (or atomic number) of the element.

16 noshells : int

17 The number of shells (>= 1).

19 latticeconstant : float, optional

20 The lattice constant. If not given, then it is extracted from

21 `ase.data`.

22 """

24 symbol, atomic_number, latticeconstant = get_element_info(

25 symbol, latticeconstant)

27 # Interpret noshells

28 if noshells < 1:

29 raise ValueError(

30 "The number of shells must be equal to or greater than one.")

32 t = 0.5 + np.sqrt(5) / 2.0

34 verticies = np.array([[t, 0., 1.],

35 [t, 0., -1.],

36 [-t, 0., 1.],

37 [-t, 0., -1.],

38 [1., t, 0.],

39 [-1., t, 0.],

40 [1., -t, 0.],

41 [-1., -t, 0.],

42 [0., 1., t],

43 [0., -1., t],

44 [0., 1., -t],

45 [0., -1., -t]])

47 positions = []

48 tags = []

49 positions.append(np.zeros(3))

50 tags.append(1)

52 for n in range(1, noshells):

53 # Construct square edges (6)

54 for k in range(0, 12, 2):

55 v1 = verticies[k]

56 v2 = verticies[k + 1]

57 for i in range(n + 1):

58 pos = i * v1 + (n - i) * v2

59 positions.append(pos)

60 tags.append(n + 1)

62 # Construct triangle planes (12)

63 if n > 1:

64 map = {0: (8, 9), 1: (10, 11),

65 2: (8, 9), 3: (10, 11),

66 4: (0, 1), 5: (2, 3),

67 6: (0, 1), 7: (2, 3),

68 8: (4, 5), 9: (6, 7),

69 10: (4, 5), 11: (6, 7)}

71 for k in range(0, 12):

72 v0 = n * verticies[k]

73 v1 = (verticies[map[k][0]] - verticies[k])

74 v2 = (verticies[map[k][1]] - verticies[k])

75 for i in range(n):

76 for j in range(n - i):

77 if i == 0 and j == 0:

78 continue

79 pos = v0 + i * v1 + j * v2

80 positions.append(pos)

81 tags.append(n + 1)

83 # Fill missing triangle planes (8)

84 if n > 2:

85 map = {0: (9, 6, 8, 4,),

86 1: (11, 6, 10, 4),

87 2: (9, 7, 8, 5,),

88 3: (11, 7, 10, 5)}

90 for k in range(0, 4):

91 v0 = n * verticies[k]

92 v1 = (verticies[map[k][0]] - verticies[k])

93 v2 = (verticies[map[k][1]] - verticies[k])

94 v3 = (verticies[map[k][2]] - verticies[k])

95 v4 = (verticies[map[k][3]] - verticies[k])

96 for i in range(1, n):

97 for j in range(1, n - i):

98 pos = v0 + i * v1 + j * v2

99 positions.append(pos)

100 tags.append(n + 1)

101 pos = v0 + i * v3 + j * v4

102 positions.append(pos)

103 tags.append(n + 1)

105 # Scale the positions

106 scaling_factor = latticeconstant / np.sqrt(2 * (1 + t**2))

107 positions = np.array(positions) * scaling_factor

109 symbols = [atomic_number] * len(positions)

110 atoms = Atoms(symbols=symbols, positions=positions, tags=tags)