Coverage for eminus/cell.py: 100.00%

33 statements  

« prev     ^ index     » next       coverage.py v7.6.4, created at 2024-11-01 11:47 +0000

1# SPDX-FileCopyrightText: 2021 The eminus developers 

2# SPDX-License-Identifier: Apache-2.0 

3"""Cell wrapper function.""" 

4 

5import numpy as np 

6 

7from .atoms import Atoms 

8from .data import LATTICE_VECTORS 

9from .utils import molecule2list 

10 

11#: Crystal structures with their respective lattice and basis. 

12STRUCTURES = { 

13 "sc": { 

14 "lattice": "sc", 

15 "basis": [[0, 0, 0]], 

16 }, 

17 "fcc": { 

18 "lattice": "fcc", 

19 "basis": [[0, 0, 0]], 

20 }, 

21 "bcc": { 

22 "lattice": "bcc", 

23 "basis": [[0, 0, 0]], 

24 }, 

25 "tetragonal": { 

26 "lattice": "sc", 

27 "basis": [[0, 0, 0]], 

28 }, 

29 "orthorhombic": { 

30 "lattice": "sc", 

31 "basis": [[0, 0, 0]], 

32 }, 

33 "hexagonal": { 

34 "lattice": "hexagonal", 

35 "basis": [[0, 0, 0]], 

36 }, 

37 "diamond": { 

38 "lattice": "fcc", 

39 "basis": [[0, 0, 0], [1 / 4, 1 / 4, 1 / 4]], 

40 }, 

41 "zincblende": { 

42 "lattice": "fcc", 

43 "basis": [[0, 0, 0], [1 / 4, 1 / 4, 1 / 4]], 

44 }, 

45 "rocksalt": { 

46 "lattice": "fcc", 

47 "basis": [[0, 0, 0], [1 / 2, 0, 0]], 

48 }, 

49 "cesiumchloride": { 

50 "lattice": "sc", 

51 "basis": [[0, 0, 0], [1 / 2, 1 / 2, 1 / 2]], 

52 }, 

53 "fluorite": { 

54 "lattice": "fcc", 

55 "basis": [[0, 0, 0], [1 / 4, 1 / 4, 1 / 4], [3 / 4, 3 / 4, 3 / 4]], 

56 }, 

57} 

58 

59 

60def Cell( 

61 atom, 

62 lattice, 

63 ecut, 

64 a, 

65 basis=None, 

66 bands=None, 

67 kmesh=1, 

68 smearing=0, 

69 magnetization=None, 

70 verbose=None, 

71 **kwargs, 

72): 

73 """Wrapper to create Atoms classes for crystal systems. 

74 

75 Args: 

76 atom: Atom symbols. 

77 lattice: Lattice system. 

78 ecut: Cut-off energy. 

79 a: Cell size. 

80 

81 Keyword Args: 

82 basis: Lattice basis. 

83 bands: Number of bands (has to be larger or equal than the occupied states). 

84 kmesh: k-point mesh. 

85 smearing: Smearing width in Hartree. 

86 magnetization: Initial magnetization. 

87 verbose: Level of output. 

88 **kwargs: Keyword arguments to pass to the Atoms object. 

89 

90 Returns: 

91 Atoms object. 

92 """ 

93 # Get the lattice vectors from a string or use them directly 

94 if isinstance(lattice, str): 

95 lattice = lattice.lower() 

96 if basis is None: 

97 basis = STRUCTURES[lattice]["basis"] 

98 lattice = STRUCTURES[lattice]["lattice"] 

99 lattice_vectors = np.asarray(LATTICE_VECTORS[lattice]) 

100 else: 

101 if basis is None: 

102 basis = [[0, 0, 0]] 

103 lattice_vectors = np.asarray(lattice) 

104 

105 # Only scale the lattice vectors with if a is given 

106 if a is not None: 

107 lattice_vectors = a * lattice_vectors 

108 basis = a * np.atleast_2d(basis) 

109 

110 # Account for different atom and basis sizes 

111 if isinstance(atom, str): 

112 atom_list = molecule2list(atom) 

113 else: 

114 atom_list = atom 

115 if len(atom_list) != len(basis): 

116 atom = [atom] * len(basis) 

117 

118 # Build the atoms object 

119 atoms = Atoms(atom, basis, ecut=ecut, a=lattice_vectors, verbose=verbose, **kwargs) 

120 # Handle k-points and states 

121 atoms.kpts.kmesh = kmesh 

122 if isinstance(lattice, str): 

123 atoms.kpts.lattice = lattice 

124 atoms.occ.smearing = smearing 

125 if bands is not None: 

126 atoms.occ.bands = bands 

127 if magnetization is not None: 

128 atoms.occ.magnetization = magnetization 

129 return atoms