Source code for sknano.generators._mwnt_generator

# -*- coding: utf-8 -*-
"""
===============================================================================
MWNT structure generator (:mod:`sknano.generators._mwnt_generator`)
===============================================================================

.. currentmodule:: sknano.generators._mwnt_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.math import Vector
from sknano.structures import MWNT
#from sknano.utils.geometric_shapes import Cuboid
from ._base import Atoms, GeneratorBase
from ._swnt_generator import SWNTGenerator

__all__ = ['MWNTGenerator']


[docs]class MWNTGenerator(MWNT, GeneratorBase): """Class for generating single, multi-walled nanotubes. .. versionchanged:: 0.2.20 `MWNTGenerator` no longer generates MWNT *bundles*, only *single* MWNTs. To generate bundled MWNT structure data, use the `MWNTBundleGenerator` class. .. versionadded:: 0.2.8 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. element1, element2 : {str, int}, optional Element symbol or atomic number of basis :class:`~sknano.core.Atom` 1 and 2 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. add_outer_shells : bool, optional Build the MWNT by adding outer shells .. versionadded:: 0.2.23 add_inner_shells : bool, optional Build the MWNT by adding inner shells .. versionadded:: 0.2.23 max_shells : int, optional Maximum number of shells per MWNT. max_shell_diameter : float, optional Maximum shell diameter, in units of **Angstroms**. min_shells : int, optional Minimum number of shells per MWNT. min_shell_diameter : float, optional Minimum shell diameter, in units of **Angstroms**. new_shell_type : {None, 'AC', 'ZZ', 'achiral', 'chiral'}, optional If `None`, the chiralities of the new shells are constrained only by their diameter and will be chosen randomly if more than one candidate chirality exists. If not `None`, then the `new_shell_type` will be added as a constraint. shell_spacing : float, optional Shell spacing in units of **Angstroms**. Default value is the van der Waals interaction distance of 3.4 Angstroms. autogen : bool, optional if `True`, automatically call :meth:`~MWNTGenerator.generate_unit_cell`, followed by :meth:`~MWNTGenerator.generate_structure_data`. verbose : bool, optional if `True`, show verbose output Examples -------- >>> from sknano.generators import MWNTGenerator >>> mwnt = MWNTGenerator(n=40, m=40, max_shells=5, Lz=1.0, fix_Lz=True) >>> mwnt.save_data() .. image:: /images/5shell_mwnt_4040_outer_Ch_1cellx1cellx4.06cells-01.png """ def __init__(self, autogen=True, **kwargs): super(MWNTGenerator, self).__init__(**kwargs) if autogen: self.generate_unit_cell() self.generate_structure_data()
[docs] def generate_unit_cell(self): """Generate the `MWNT` unit cell.""" self.unit_cell = Atoms() for swnt in self.shells: self.unit_cell.extend(SWNTGenerator(**swnt.todict()).unit_cell)
[docs] def generate_structure_data(self): """Generate structure data. .. todo:: Load the diameter and chirality data from file instead of generating it every time. """ #self.atoms = Atoms(atoms=self.unit_cell) #self.atoms = Atoms() self.structure_data.clear() for swnt in self.shells: self.atoms.extend(SWNTGenerator(**swnt.todict()).atoms)
#for n, m in self.Ch: #for nz in xrange(int(np.ceil(self.nz))): # dr = Vector([0.0, 0.0, nz * self.T]) # for uc_atom in self.unit_cell: # nt_atom = Atom(element=uc_atom.symbol) # nt_atom.r = uc_atom.r + dr # self.atoms.append(nt_atom) #Lzmin = self.atoms #pmin = [-np.inf, -np.inf, -np.inf] #pmax = [np.inf, np.inf, np.inf] #region_bounds = Cuboid(pmin=pmin, pmax=pmax) #if self.L0 is not None and self.fix_Lz: # region_bounds.zmax = (10 * self.L0 + 1) / 2 #else: # region_bounds.zmax = (10 * Lzmin + 1) / 2 #region_bounds.zmin = -region_bounds.zmax #region_bounds.update_region_limits() #self.atoms.clip_bounds(region_bounds, # center_before_clipping=True)
[docs] def save_data(self, fname=None, outpath=None, structure_format=None, rotation_angle=None, rot_axis=None, deg2rad=True, anchor_point=None, center_CM=True, savecopy=True, **kwargs): """Save structure data. See :meth:`~sknano.generators.GeneratorBase.save_data` method for documentation. """ if fname is None: Nshells = '{}shell_mwnt'.format(self.Nshells) chiralities = '@'.join([str(Ch).replace(' ', '') for Ch in self.Ch]) fname_wordlist = None #if self._assert_integer_nz: # nz = ''.join(('{}'.format(self.nz), # pluralize('cell', self.nz))) #else: # nz = ''.join(('{:.2f}'.format(self.nz), # pluralize('cell', self.nz))) #fname_wordlist = (Nshells, chiralities, nz) fname_wordlist = (Nshells, chiralities) fname = '_'.join(fname_wordlist) super(MWNTGenerator, self).save_data( fname=fname, outpath=outpath, structure_format=structure_format, rotation_angle=rotation_angle, rot_axis=rot_axis, anchor_point=anchor_point, deg2rad=deg2rad, center_CM=center_CM, savecopy=savecopy, **kwargs)