Source code for sknano.generators._unrolled_swnt_generator

# -*- coding: utf-8 -*-
"""
===============================================================================
Unrolled SWNT generator (:mod:`sknano.generators._unrolled_swnt_generator`)
===============================================================================

.. currentmodule:: sknano.generators._unrolled_swnt_generator

.. todo::

   Add methods to perform fractional translation and cartesian translation
   before structure generation.

.. todo::

   Handle different units in output coordinates.

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

import copy

import numpy as np

from sknano.core import pluralize
from sknano.core.crystallography import SuperCell
from sknano.core.math import Vector
from sknano.structures import UnrolledSWNT
# from sknano.core.geometric_regions import Cuboid
from ._base import Atom, Atoms, GeneratorBase

__all__ = ['UnrolledSWNTGenerator']


[docs]class UnrolledSWNTGenerator(GeneratorBase, UnrolledSWNT): """Class for generating unrolled nanotube structures. .. versionadded:: 0.2.23 Parameters ---------- n, m : int Chiral indices defining the nanotube chiral vector :math:`\\mathbf{C}_{h} = n\\mathbf{a}_{1} + m\\mathbf{a}_{2} = (n, m)`. nx, ny, nz : int, optional Number of repeat unit cells in the :math:`x, y, z` dimensions basis : {:class:`python:list`}, optional List of :class:`python:str`\ s of element symbols or atomic number of the two atom basis (default: ['C', 'C']) .. versionadded:: 0.3.10 element1, element2 : {str, int}, optional Element symbol or atomic number of basis :class:`~sknano.core.Atom` 1 and 2 .. deprecated:: 0.3.10 Use `basis` instead bond : float, optional :math:`\\mathrm{a}_{\\mathrm{CC}} =` distance between nearest neighbor atoms. Must be in units of **Angstroms**. Lx, Ly, Lz : float, optional Length of bundle in :math:`x, y, z` dimensions in **nanometers**. Overrides the :math:`n_x, n_y, n_z` cell values. fix_Lz : bool, optional Generate the nanotube with length as close to the specified :math:`L_z` as possible. If `True`, then non integer :math:`n_z` cells are permitted. autogen : bool, optional if `True`, automatically call :meth:`~UnrolledSWNTGenerator.generate`. verbose : bool, optional if `True`, show verbose output Notes ----- The `UnrolledSWNTGenerator` class generates graphene using the nanotube unit cell defined by the chiral vector :math:`\\mathbf{C}_{h} = n\\mathbf{a}_{1} + m\\mathbf{a}_{2} = (n, m)`. If you want to generate graphene with an armchair or zigzag edge using `length` and `width` parameters, see the :class:`~sknano.generators.GrapheneGenerator` class. .. seealso:: :class:`~sknano.generators.GrapheneGenerator` Examples -------- First, load the :class:`~sknano.generators.UnrolledSWNTGenerator` class. >>> from sknano.generators import UnrolledSWNTGenerator Now let's generate an unrolled :math:`\\mathbf{C}_{\\mathrm{h}} = (10, 5)` SWCNT unit cell. >>> flatswcnt = UnrolledSWNTGenerator(10, 5) >>> flatswcnt.save() The rendered structure looks like: """
[docs] def generate(self): """Generate structure data.""" self.structure_data.clear() layer0 = Atoms() scaling_matrix = [int(np.ceil(self.nx)), 1, int(np.ceil(self.nz))] for atom in SuperCell(self.unit_cell, scaling_matrix): layer0.append(Atom(**atom.todict())) layer0.center_centroid() self.layers = [] for nlayer in range(self.nlayers): layer = copy.deepcopy(layer0) layer.translate(Vector([0, nlayer * self.layer_spacing, 0])) [setattr(atom, 'mol', nlayer + 1) for atom in layer] if (nlayer % 2) != 0: layer.translate(self.layer_shift) layer.rotate(angle=self.layer_rotation_angles[nlayer], axis='z') self.atoms.extend(layer) self.layers.append(layer)
@classmethod
[docs] def generate_fname(cls, n=None, m=None, nx=None, nz=None, fix_Lx=False, fix_Lz=False, **kwargs): chirality = '{}{}'.format('{}'.format(n).zfill(2), '{}'.format(m).zfill(2)) nx_fmtstr = '{:.2f}' if fix_Lx else '{:.0f}' nx = ''.join((nx_fmtstr.format(nx), pluralize('cell', nx))) nz_fmtstr = '{:.2f}' if fix_Lz else '{:.0f}' nz = ''.join((nz_fmtstr.format(nz), pluralize('cell', nz))) cells = 'x'.join((nx, nz)) fname_wordlist = (chirality, cells) fname = 'unrolled_' + '_'.join(fname_wordlist) return fname
[docs] def save(self, fname=None, outpath=None, structure_format=None, center_centroid=True, **kwargs): """Save structure data. See :meth:`~sknano.generators.GeneratorBase.save` method for documentation. """ if fname is None: fname = self.generate_fname(n=self.n, m=self.m, nx=self.nx, nz=self.nz, fix_Lx=self.fix_Lx, fix_Lz=self.fix_Lz) if center_centroid: self.atoms.center_centroid() super().save(fname=fname, outpath=outpath, structure_format=structure_format, center_centroid=False, **kwargs)