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

1# fmt: off 

2 

3import numpy as np 

4 

5from ase import Atoms 

6from ase.cluster.util import get_element_info 

7 

8 

9def Decahedron(symbol, p, q, r, latticeconstant=None): 

10 """ 

11 Return a decahedral cluster. 

12 

13 Parameters 

14 ---------- 

15 symbol: Chemical symbol (or atomic number) of the element. 

16 

17 p: Number of atoms on the (100) facets perpendicular to the five 

18 fold axis. 

19 

20 q: Number of atoms on the (100) facets parallel to the five fold 

21 axis. q = 1 corresponds to no visible (100) facets. 

22 

23 r: Depth of the Marks re-entrence at the pentagon corners. r = 0 

24 corresponds to no re-entrence. 

25 

26 latticeconstant (optional): The lattice constant. If not given, 

27 then it is extracted form ase.data. 

28 """ 

29 

30 symbol, atomic_number, latticeconstant = get_element_info( 

31 symbol, latticeconstant) 

32 

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.") 

36 

37 if r < 0: 

38 raise ValueError("r must be greater than or equal to 0.") 

39 

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 

44 

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.]]) 

54 

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 

58 

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) 

64 

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) 

80 

81 symbols = [atomic_number] * len(positions) 

82 return Atoms(symbols=symbols, positions=positions)