Source code for sknano.structures._graphene
# -*- coding: utf-8 -*-
"""
===============================================================================
Graphene structure classes (:mod:`sknano.structures._graphene`)
===============================================================================
.. currentmodule:: sknano.structures._graphene
"""
from __future__ import absolute_import, division, print_function
__docformat__ = 'restructuredtext en'
#import itertools
import numbers
import numpy as np
#from sknano.core.atoms import Atom
from sknano.core.math import Vector
from sknano.core.refdata import dVDW # , grams_per_Da
from ._base import StructureBase
from ._extras import edge_types
__all__ = ['GraphenePrimitiveCell', 'Graphene']
[docs]class GraphenePrimitiveCell(StructureBase):
"""Graphene primitive unit cell structure class.
Parameters
----------
bond : float, optional
bond length between nearest-neighbor atoms in **Angstroms**.
"""
def __init__(self, **kwargs):
super(GraphenePrimitiveCell, self).__init__(**kwargs)
self.a = np.sqrt(3) * self.bond
self.a1 = Vector(nd=2)
self.a2 = Vector(nd=2)
self.a1.x = self.a2.x = np.sqrt(3) / 2 * self.a
self.a1.y = 1 / 2 * self.a
self.a2.y = -self.a1.y
self.b1 = Vector(nd=2)
self.b2 = Vector(nd=2)
self.b1.x = self.b2.x = 1 / np.sqrt(3) * 2 * np.pi / self.a
self.b1.y = 2 * np.pi / self.a
self.b2.y = -self.b1.y
[docs]class Graphene(StructureBase):
"""Graphene structure class.
Parameters
----------
length : float, optional
Length of graphene sheet in **nanometers**
width : float, optional
Width of graphene sheet in **nanometers**
edge : {'AC', 'armchair', 'ZZ', 'zigzag'}, optional
**A**\ rm\ **C**\ hair or **Z**\ ig\ **Z**\ ag edge along
the `length` of the sheet.
element1, element2 : {str, int}, optional
Element symbol or atomic number of basis
:class:`~sknano.core.atoms.Atom` 1 and 2
bond : float, optional
bond length between nearest-neighbor atoms in **Angstroms**.
nlayers : int, optional
Number of graphene layers.
layer_spacing : float, optional
Distance between layers in **Angstroms**.
stacking_order : {'AA', 'AB'}, optional
Stacking order of graphene layers
verbose : bool, optional
verbose output
Notes
-----
For now, the graphene structure is generated using a
conventional unit cell, not the primitive unit cell.
.. todo::
Add notes on unit cell calculation.
"""
def __init__(self, length=None, width=None, edge=None, nlayers=1,
layer_spacing=dVDW, layer_rotation_angles=None,
stacking_order='AB', deg2rad=True, **kwargs):
super(Graphene, self).__init__(**kwargs)
self.length = length
self.width = width
if edge in ('armchair', 'zigzag'):
edge = edge_types[edge]
elif edge not in ('AC', 'ZZ'):
print('unrecognized edge parameter: {}\n'.format(edge) +
'choosing one at random...\n')
edge = np.random.choice(['AC', 'ZZ'])
print('the randomly chosen edge type is: {}'.format(edge))
self.edge = edge
self._Nx = 0
self._Ny = 0
self.layer_mass = None
self.Natoms = 0
self.Natoms_per_layer = 0
self.nlayers = nlayers
self.layer_spacing = layer_spacing
if layer_rotation_angles is not None and deg2rad:
if isinstance(layer_rotation_angles, numbers.Number):
layer_rotation_angles = np.radians(layer_rotation_angles)
elif isinstance(layer_rotation_angles, (list, np.ndarray)):
layer_rotation_angles = \
np.radians(np.asarray(layer_rotation_angles)).tolist()
self.layer_rotation_angles = layer_rotation_angles
self.stacking_order = stacking_order
self.layer_shift = Vector()
if nlayers > 1 and stacking_order == 'AB':
if edge == 'AC':
self.layer_shift.y = self.bond
else:
self.layer_shift.x = self.bond
self.cell = Vector()
if edge == 'AC':
# Set up the unit cell with the armchair edge aligned
# along the `y`-axis.
self.cell.x = np.sqrt(3) * self.bond
self.cell.y = 3 * self.bond
else:
# Set up the unit cell with the zigzag edge aligned
# along the `y`-axis.
self.cell.x = 3 * self.bond
self.cell.y = np.sqrt(3) * self.bond
self.Nx = int(np.ceil(10 * self.width / self.cell.x))
self.Ny = int(np.ceil(10 * self.length / self.cell.y))
def __repr__(self):
retstr = 'Graphene(length={!r}, width={!r}, edge={!r}, ' + \
'element1={!r}, element2={!r}, bond={!r}, nlayers={!r}, ' + \
'layer_spacing={!r}, layer_rotation_angles={!r}, ' + \
'stacking_order={!r})'
return retstr.format(self.length, self.width, self.edge, self.element1,
self.element2, self.bond, self.nlayers,
self.layer_spacing, self.layer_rotation_angles,
self.stacking_order)