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