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
|
"""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()
|