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 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: The chemical symbol (or atomic number) of the element.
15 noshells: The number of shells (>= 1).
17 latticeconstant (optional): The lattice constant. If not given,
18 then it is extracted form ase.data.
19 """
21 symbol, atomic_number, latticeconstant = get_element_info(
22 symbol, latticeconstant)
24 # Interpret noshells
25 if noshells < 1:
26 raise ValueError(
27 "The number of shells must be equal to or greater than one.")
29 t = 0.5 + np.sqrt(5) / 2.0
31 verticies = np.array([[t, 0., 1.],
32 [t, 0., -1.],
33 [-t, 0., 1.],
34 [-t, 0., -1.],
35 [1., t, 0.],
36 [-1., t, 0.],
37 [1., -t, 0.],
38 [-1., -t, 0.],
39 [0., 1., t],
40 [0., -1., t],
41 [0., 1., -t],
42 [0., -1., -t]])
44 positions = []
45 tags = []
46 positions.append(np.zeros(3))
47 tags.append(1)
49 for n in range(1, noshells):
50 # Construct square edges (6)
51 for k in range(0, 12, 2):
52 v1 = verticies[k]
53 v2 = verticies[k + 1]
54 for i in range(n + 1):
55 pos = i * v1 + (n - i) * v2
56 positions.append(pos)
57 tags.append(n + 1)
59 # Construct triangle planes (12)
60 if n > 1:
61 map = {0: (8, 9), 1: (10, 11),
62 2: (8, 9), 3: (10, 11),
63 4: (0, 1), 5: (2, 3),
64 6: (0, 1), 7: (2, 3),
65 8: (4, 5), 9: (6, 7),
66 10: (4, 5), 11: (6, 7)}
68 for k in range(0, 12):
69 v0 = n * verticies[k]
70 v1 = (verticies[map[k][0]] - verticies[k])
71 v2 = (verticies[map[k][1]] - verticies[k])
72 for i in range(n):
73 for j in range(n - i):
74 if i == 0 and j == 0:
75 continue
76 pos = v0 + i * v1 + j * v2
77 positions.append(pos)
78 tags.append(n + 1)
80 # Fill missing triangle planes (8)
81 if n > 2:
82 map = {0: (9, 6, 8, 4,),
83 1: (11, 6, 10, 4),
84 2: (9, 7, 8, 5,),
85 3: (11, 7, 10, 5)}
87 for k in range(0, 4):
88 v0 = n * verticies[k]
89 v1 = (verticies[map[k][0]] - verticies[k])
90 v2 = (verticies[map[k][1]] - verticies[k])
91 v3 = (verticies[map[k][2]] - verticies[k])
92 v4 = (verticies[map[k][3]] - verticies[k])
93 for i in range(1, n):
94 for j in range(1, n - i):
95 pos = v0 + i * v1 + j * v2
96 positions.append(pos)
97 tags.append(n + 1)
98 pos = v0 + i * v3 + j * v4
99 positions.append(pos)
100 tags.append(n + 1)
102 # Scale the positions
103 scaling_factor = latticeconstant / np.sqrt(2 * (1 + t**2))
104 positions = np.array(positions) * scaling_factor
106 symbols = [atomic_number] * len(positions)
107 atoms = Atoms(symbols=symbols, positions=positions, tags=tags)
108 atoms.center(about=(0, 0, 0))
109 atoms.cell[:] = 0
110 return atoms