Coverage for eminus/cell.py: 100.00%
33 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-18 08:43 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-18 08:43 +0000
1# SPDX-FileCopyrightText: 2021 The eminus developers
2# SPDX-License-Identifier: Apache-2.0
3"""Cell wrapper function."""
5import numpy as np
7from .atoms import Atoms
8from .data import LATTICE_VECTORS
9from .utils import molecule2list
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}
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.
75 Args:
76 atom: Atom symbols.
77 lattice: Lattice system.
78 ecut: Cut-off energy.
79 a: Cell size.
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.
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)
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)
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)
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