1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
"""Function-like objects creating orthorhombic lattices.
The following lattice creators are defined:
SimleOrthorhombic
BaseCenteredOrthorhombic
BodyCenteredOrthorhombic
FaceCenteredOrthorhombic
"""
import numpy as np
from ase.data import reference_states as _refstate
from ase.lattice.bravais import Bravais
class SimpleOrthorhombicFactory(Bravais):
"A factory for creating simple orthorhombic lattices."
# The name of the crystal structure in ChemicalElements
xtal_name = "orthorhombic"
# The natural basis vectors of the crystal structure
int_basis = np.array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
basis_factor = 1.0
# Converts the natural basis back to the crystallographic basis
inverse_basis = np.array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
inverse_basis_factor = 1.0
def get_lattice_constant(self):
"""Get the lattice constant of an element with orhtorhombic
crystal structure."""
if _refstate[self.atomicnumber]['symmetry'] != self.xtal_name:
raise ValueError(("Cannot guess the %s lattice constant of"
+ " an element with crystal structure %s.")
% (self.xtal_name,
_refstate[self.atomicnumber]['symmetry']))
return _refstate[self.atomicnumber].copy()
def make_crystal_basis(self):
"""Make the basis matrix for the crystal unit cell and the system unit
cell."""
lattice = self.latticeconstant
if isinstance(lattice, type({})):
a = lattice['a']
try:
b = lattice['b']
except KeyError:
b = a * lattice['b/a']
try:
c = lattice['c']
except KeyError:
c = a * lattice['c/a']
else:
if len(lattice) == 3:
(a, b, c) = lattice
else:
raise ValueError(
"Improper lattice constants for orthorhombic crystal.")
lattice = np.array([[a, 0, 0], [0, b, 0], [0, 0, c]])
self.latticeconstant = lattice
self.miller_basis = lattice
self.crystal_basis = (self.basis_factor *
np.dot(self.int_basis, lattice))
self.basis = np.dot(self.directions, self.crystal_basis)
self.check_basis_volume()
def check_basis_volume(self):
"Check the volume of the unit cell."
vol1 = abs(np.linalg.det(self.basis))
vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant)
if self.bravais_basis is not None:
vol2 /= len(self.bravais_basis)
if abs(vol1 - vol2) > 1e-5:
print(f"WARNING: Got volume {vol1:f}, expected {vol2:f}")
SimpleOrthorhombic = SimpleOrthorhombicFactory()
class BaseCenteredOrthorhombicFactory(SimpleOrthorhombicFactory):
"A factory for creating base-centered orthorhombic lattices."
# The natural basis vectors of the crystal structure
int_basis = np.array([[1, -1, 0],
[1, 1, 0],
[0, 0, 2]])
basis_factor = 0.5
# Converts the natural basis back to the crystallographic basis
inverse_basis = np.array([[1, 1, 0],
[-1, 1, 0],
[0, 0, 1]])
inverse_basis_factor = 1.0
def check_basis_volume(self):
"Check the volume of the unit cell."
vol1 = abs(np.linalg.det(self.basis))
vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant) / 2.0
if abs(vol1 - vol2) > 1e-5:
print(f"WARNING: Got volume {vol1:f}, expected {vol2:f}")
BaseCenteredOrthorhombic = BaseCenteredOrthorhombicFactory()
class BodyCenteredOrthorhombicFactory(SimpleOrthorhombicFactory):
"A factory for creating body-centered orthorhombic lattices."
int_basis = np.array([[-1, 1, 1],
[1, -1, 1],
[1, 1, -1]])
basis_factor = 0.5
inverse_basis = np.array([[0, 1, 1],
[1, 0, 1],
[1, 1, 0]])
inverse_basis_factor = 1.0
def check_basis_volume(self):
"Check the volume of the unit cell."
vol1 = abs(np.linalg.det(self.basis))
vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant) / 2.0
if abs(vol1 - vol2) > 1e-5:
print(f"WARNING: Got volume {vol1:f}, expected {vol2:f}")
BodyCenteredOrthorhombic = BodyCenteredOrthorhombicFactory()
class FaceCenteredOrthorhombicFactory(SimpleOrthorhombicFactory):
"A factory for creating face-centered orthorhombic lattices."
int_basis = np.array([[0, 1, 1],
[1, 0, 1],
[1, 1, 0]])
basis_factor = 0.5
inverse_basis = np.array([[-1, 1, 1],
[1, -1, 1],
[1, 1, -1]])
inverse_basis_factor = 1.0
def check_basis_volume(self):
"Check the volume of the unit cell."
vol1 = abs(np.linalg.det(self.basis))
vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant) / 4.0
if abs(vol1 - vol2) > 1e-5:
print(f"WARNING: Got volume {vol1:f}, expected {vol2:f}")
FaceCenteredOrthorhombic = FaceCenteredOrthorhombicFactory()
|