Source code for sknano.generators._bilayer_graphene_generator

# -*- coding: utf-8 -*-
"""
===============================================================================
Bilayer Graphene (:mod:`sknano.generators._bilayer_graphene_generator`)
===============================================================================

.. currentmodule:: sknano.generators._bilayer_graphene_generator

"""
from __future__ import absolute_import, division, print_function
__docformat__ = 'restructuredtext en'

import copy

import numpy as np

from sknano.structures import BilayerGraphene
from ._base import Atoms, GeneratorBase

__all__ = ['BilayerGrapheneGenerator']


[docs]class BilayerGrapheneGenerator(BilayerGraphene, GeneratorBase): """Bilayer graphene structure generator class. Parameters ---------- length : float Length of graphene sheet in **nanometers** width : float 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**. layer_spacing : float, optional Distance between layers in **Angstroms**. stacking_order : {'AA', 'AB'}, optional Stacking order of graphene layers layer_rotation_angle : {None, float}, optional Rotation angle of second layer specified in degrees. If specified in radians, then you must set `deg2rad=False` deg2rad : bool, optional The `layer_rotation_angle` is specified in degrees and needs to be converted to radians. autogen : bool, optional if `True`, automatically generate unit cell and full structure verbose : bool, optional verbose output Examples -------- Import the BilayerGrapheneGenerator class >>> from sknano.generators import BilayerGrapheneGenerator Generate **10 nm** wide by **1 nm** long `AB` stacked bilayer-graphene with a `ZZ` edge: >>> bi_graphene = BilayerGrapheneGenerator(length=10, width=1, edge='ZZ') Save structure data in `xyz` format: >>> bi_graphene.save_data() The rendered structure looks like (after rotating 90 degrees so that it better fits the page): .. image:: /images/10nmx1nm_bilayer.png Now generate bilayer-graphene with top layer rotated by 45 degrees. >>> rotated_bilayer = BilayerGrapheneGenerator(length=10, width=10, ... edge='armchair', ... layer_rotation_angle=45) >>> rotated_bilayer.save_data(fname='rotated_bilayer.xyz') The rendered structure looks like: .. image:: /images/rotated_bilayer.png Now generate BN bilayer-graphene with top layer rotated 45 degrees. >>> rotated_BN_bilayer = BilayerGrapheneGenerator(length=10, width=10, ... edge='zigzag', ... element1='B', ... element2='N', ... layer_rotation_angle=45) >>> rotated_BN_bilayer.save_data(fname='BN_bilayer_rotated_45deg.xyz') The rendered structure looks like: .. image:: /images/BN_bilayer_rotated_45deg.png """ def __init__(self, autogen=True, **kwargs): super(BilayerGrapheneGenerator, self).__init__(**kwargs) if autogen: super(BilayerGrapheneGenerator, self).generate_unit_cell() self.generate_structure_data()
[docs] def generate_structure_data(self): """Generate the full structure coordinates.""" super(BilayerGrapheneGenerator, self).generate_structure_data() if self.layer_rotation_angle is not None: bilayer = copy.deepcopy(self.atoms) self.atoms = Atoms() z_coords = bilayer.get_coords(asdict=True)['z'] z_set = np.asarray(sorted(list(set(z_coords)))) epsilon = 1e-10 for n, z in enumerate(z_set): layer = Atoms(atoms=bilayer.get_atoms(asarray=True)[ np.where(np.abs(z_coords - z) < epsilon)].tolist(), deepcopy=True) if (n % 2) != 0: layer.rotate(angle=self.layer_rotation_angle, rot_axis='z') self.atoms.extend(layer.atoms)