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.
126 lines
4.1 KiB
126 lines
4.1 KiB
"""Function-like object creating hexagonal lattices. |
|
|
|
The following lattice creators are defined: |
|
|
|
* Hexagonal |
|
* HexagonalClosedPacked |
|
* Graphite |
|
* Graphene |
|
|
|
Example for using Graphene to create atoms object gra:: |
|
|
|
from ase.lattice.hexagonal import * |
|
import ase.io as io |
|
from ase import Atoms, Atom |
|
|
|
index1=6 |
|
index2=7 |
|
mya = 2.45 |
|
myc = 20.0 |
|
|
|
gra = Graphene(symbol = 'C',latticeconstant={'a':mya,'c':myc}, |
|
size=(index1,index2,1)) |
|
io.write('test.xyz', gra, format='xyz') |
|
""" |
|
|
|
from ase.lattice.triclinic import TriclinicFactory |
|
|
|
|
|
class HexagonalFactory(TriclinicFactory): |
|
"A factory for creating simple hexagonal lattices." |
|
# The name of the crystal structure in ChemicalElements |
|
xtal_name = "hexagonal" |
|
|
|
def make_crystal_basis(self): |
|
"""Make the basis matrix for the crystal and system unit cells.""" |
|
# First convert the basis specification to a triclinic one |
|
if isinstance(self.latticeconstant, type({})): |
|
self.latticeconstant['alpha'] = 90 |
|
self.latticeconstant['beta'] = 90 |
|
self.latticeconstant['gamma'] = 120 |
|
self.latticeconstant['b/a'] = 1.0 |
|
else: |
|
if len(self.latticeconstant) == 2: |
|
a, c = self.latticeconstant |
|
self.latticeconstant = (a, a, c, 90, 90, 120) |
|
else: |
|
raise ValueError( |
|
"Improper lattice constants for hexagonal crystal.") |
|
TriclinicFactory.make_crystal_basis(self) |
|
|
|
def find_directions(self, directions, miller): |
|
"""Find missing directions and miller indices from the specified ones. |
|
|
|
Also handles the conversion of hexagonal-style 4-index notation to |
|
the normal 3-index notation. |
|
""" |
|
directions = list(directions) |
|
miller = list(miller) |
|
if miller != [None, None, None]: |
|
raise NotImplementedError( |
|
'Specifying Miller indices of surfaces currently ' |
|
'broken for hexagonal crystals.') |
|
for obj in (directions, miller): |
|
for i in range(3): |
|
if obj[i] is not None: |
|
(a, b, c, d) = obj[i] |
|
if a + b + c != 0: |
|
raise ValueError( |
|
("(%d,%d,%d,%d) is not a valid hexagonal Miller " + |
|
"index, as the sum of the first three numbers " + |
|
"should be zero.") % (a, b, c, d)) |
|
x = 4 * a + 2 * b |
|
y = 2 * a + 4 * b |
|
z = 3 * d |
|
obj[i] = (x, y, z) |
|
TriclinicFactory.find_directions(self, directions, miller) |
|
|
|
def print_directions_and_miller(self, txt=""): |
|
"Print direction vectors and Miller indices." |
|
print("Direction vectors of unit cell%s:" % (txt,)) |
|
for i in (0, 1, 2): |
|
self.print_four_vector("[]", self.directions[i]) |
|
print("Miller indices of surfaces%s:" % (txt,)) |
|
for i in (0, 1, 2): |
|
self.print_four_vector("()", self.miller[i]) |
|
|
|
def print_four_vector(self, bracket, numbers): |
|
bra, ket = bracket |
|
(x, y, z) = numbers |
|
a = 2 * x - y |
|
b = -x + 2 * y |
|
c = -x - y |
|
d = 2 * z |
|
print(" %s%d, %d, %d%s ~ %s%d, %d, %d, %d%s" % |
|
(bra, x, y, z, ket, bra, a, b, c, d, ket)) |
|
|
|
|
|
Hexagonal = HexagonalFactory() |
|
|
|
|
|
class HexagonalClosedPackedFactory(HexagonalFactory): |
|
"A factory for creating HCP lattices." |
|
xtal_name = "hcp" |
|
bravais_basis = [[0, 0, 0], [1.0 / 3.0, 2.0 / 3.0, 0.5]] |
|
|
|
|
|
HexagonalClosedPacked = HexagonalClosedPackedFactory() |
|
|
|
|
|
class GraphiteFactory(HexagonalFactory): |
|
"A factory for creating graphite lattices." |
|
xtal_name = "graphite" |
|
bravais_basis = [[0, 0, 0], [1.0 / 3.0, 2.0 / 3.0, 0], |
|
[1.0 / 3.0, 2.0 / 3.0, 0.5], [2.0 / 3.0, 1.0 / 3.0, 0.5]] |
|
|
|
|
|
Graphite = GraphiteFactory() |
|
|
|
|
|
class GrapheneFactory(HexagonalFactory): |
|
"A factory for creating graphene lattices." |
|
xtal_name = "graphene" |
|
bravais_basis = [[0, 0, 0], [1.0 / 3.0, 2.0 / 3.0, 0]] |
|
|
|
|
|
Graphene = GrapheneFactory()
|
|
|