Coverage for /builds/kinetik161/ase/ase/cluster/decahedron.py: 93.75%
32 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-12-10 11:04 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-12-10 11:04 +0000
1import numpy as np
3from ase import Atoms
4from ase.cluster.util import get_element_info
7def Decahedron(symbol, p, q, r, latticeconstant=None):
8 """
9 Return a decahedral cluster.
11 Parameters
12 ----------
13 symbol: Chemical symbol (or atomic number) of the element.
15 p: Number of atoms on the (100) facets perpendicular to the five
16 fold axis.
18 q: Number of atoms on the (100) facets parallel to the five fold
19 axis. q = 1 corresponds to no visible (100) facets.
21 r: Depth of the Marks re-entrence at the pentagon corners. r = 0
22 corresponds to no re-entrence.
24 latticeconstant (optional): The lattice constant. If not given,
25 then it is extracted form ase.data.
26 """
28 symbol, atomic_number, latticeconstant = get_element_info(
29 symbol, latticeconstant)
31 # Check values of p, q, r
32 if p < 1 or q < 1:
33 raise ValueError("p and q must be greater than 0.")
35 if r < 0:
36 raise ValueError("r must be greater than or equal to 0.")
38 # Defining constants
39 t = 2.0 * np.pi / 5.0
40 b = latticeconstant / np.sqrt(2.0)
41 a = b * np.sqrt(3.0) / 2.0
43 verticies = a * np.array([[np.cos(np.pi / 2.), np.sin(np.pi / 2.), 0.],
44 [np.cos(t * 1. + np.pi / 2.),
45 np.sin(t * 1. + np.pi / 2.), 0.],
46 [np.cos(t * 2. + np.pi / 2.),
47 np.sin(t * 2. + np.pi / 2.), 0.],
48 [np.cos(t * 3. + np.pi / 2.),
49 np.sin(t * 3. + np.pi / 2.), 0.],
50 [np.cos(t * 4. + np.pi / 2.), np.sin(
51 t * 4. + np.pi / 2.), 0.]])
53 # Number of atoms on the five fold axis and a nice constant
54 h = p + q + 2 * r - 1
55 g = h - q + 1 # p + 2*r
57 positions = []
58 # Make the five fold axis
59 for j in range(h):
60 pos = np.array([0.0, 0.0, j * b - (h - 1) * b / 2.0])
61 positions.append(pos)
63 # Make pentagon rings around the five fold axis
64 for n in range(1, h):
65 # Condition for (100)-planes
66 if n < g:
67 for m in range(5):
68 v1 = verticies[m - 1]
69 v2 = verticies[m]
70 for i in range(n):
71 # Condition for marks re-entrence
72 if n - i < g - r and i < g - r:
73 for j in range(h - n):
74 pos = (n - i) * v1 + i * v2
75 pos += np.array([0.0, 0.0, j * b -
76 (h - n - 1) * b / 2.0])
77 positions.append(pos)
79 symbols = [atomic_number] * len(positions)
80 return Atoms(symbols=symbols, positions=positions)