A series of Python3 script to lower the barrier of computing and simulating molecular and material systems.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
5.3 KiB

2 years ago
"""Function-like objects creating orthorhombic lattices.
The following lattice creators are defined:
SimleOrthorhombic
BaseCenteredOrthorhombic
BodyCenteredOrthorhombic
FaceCenteredOrthorhombic
"""
from ase.lattice.bravais import Bravais
import numpy as np
from ase.data import reference_states as _refstate
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("WARNING: Got volume %f, expected %f" % (vol1, vol2))
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("WARNING: Got volume %f, expected %f" % (vol1, vol2))
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("WARNING: Got volume %f, expected %f" % (vol1, vol2))
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("WARNING: Got volume %f, expected %f" % (vol1, vol2))
FaceCenteredOrthorhombic = FaceCenteredOrthorhombicFactory()