Source code for sknano.generators.mwnt_generator

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

.. currentmodule:: sknano.generators.mwnt_generator

"""
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 Point
from sknano.core.structures import MWNT
from sknano.core.geometric_regions import Cuboid
from .base import NanoStructureGenerator
from .nanotube_bundle_generator import NanotubeBundleGeneratorBase
from .swnt_generator import SWNTGenerator

__all__ = ['MWNTGeneratorBase', 'MWNTGenerator']


[docs]class MWNTGeneratorBase(NanoStructureGenerator): """Mixin :class:`~sknano.core.structures.MWNT` structure generator."""
[docs] def generate(self, finalize=True): """Generate structure data. .. todo:: Load the diameter and chirality data from file instead of generating it every time. """ self.structure.clear() for swnt in self.walls: self.atoms.extend(SWNTGenerator(finalize=False, **swnt.todict()).atoms) if finalize: self.finalize()
[docs]class MWNTGenerator(NanotubeBundleGeneratorBase, MWNTGeneratorBase, MWNT): """Class for generating multi-walled nanotubes (MWNT). .. versionchanged:: 0.4.0 `MWNTGenerator` now generates both *single* MWNTs and MWNT bundles. .. versionadded:: 0.2.8 Parameters ---------- Ch_list : :class:`python:list`, optional (:attr:`~SWNT.n`, :attr:`~SWNT.m`) for each `SWNT` wall in `MWNT`. Nwalls : int, optional Number of `SWNT` walls in `MWNT`. Lz : float, optional `MWNT` length in **Angstroms**. min_wall_diameter : float, optional Minimum `MWNT` wall diameter, in units of **Angstroms**. max_wall_diameter : float, optional Maximum `MWNT` wall diameter, in units of **Angstroms**. max_walls : int, optional Maximum number of `MWNT` walls. chiral_types : {None, 'armchair', 'zigzag', 'achiral', 'chiral'}, optional If `None`, the :attr:`~SWNT.chiral_type` of each `MWNT` walls will be random and determined by the set of randomly selected chiral indices (:attr:`~SWNT.n`, :attr:`~SWNT.m`). wall_spacing : float, optional Inter-wall spacing in units of **Angstroms**. Default value is the van der Waals interaction distance of 3.4 Angstroms. nx, ny : int, optional Number of repeat unit cells in the :math:`x, y` dimensions. vdw_radius : float, optional van der Waals radius of nanotube atoms 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, in units of **Angstroms**. bundle_packing : {'hcp', 'ccp'}, optional Packing arrangement of MWNT bundles. If `bundle_packing` is `None`, then it will be determined by the `bundle_geometry` parameter if `bundle_geometry` is not `None`. If both `bundle_packing` and `bundle_geometry` are `None`, then `bundle_packing` defaults to `hcp`. bundle_geometry : {'triangle', 'hexagon', 'square', 'rectangle'}, optional autogen : bool, optional if `True`, automatically call :meth:`~MWNTGenerator.generate`. verbose : bool, optional if `True`, show verbose output Examples -------- >>> from sknano.generators import MWNTGenerator >>> MWNTGenerator(Nwalls=5, min_wall_diameter=10, Lz=50).save() The above command generated a 5 wall, 50 **Angstrom** long `MWNT`. The only constraints on the `MWNT` wall chiralities were the diameter constraints imposed by the `min_wall_diameter` parameter, which set the minimum wall diameter to 10 Angstroms, as well as the minimum wall-to-wall separation, which defaults to the van der Waals distance of 3.4 Angstroms. This `MWNT` chirality may be written as: :math:`\\mathbf{C}_{\\mathrm{h}} = (8,7)@(17,8)@(9,24)@(27,18)@(22,32)` Here's a colorful rendering of the generated `MWNT` structure: .. image:: /images/5wall_mwnt_(8,7)@(17,8)@(9,24)@(27,18)@(22,32)-04.png In the next example, we generate a `MWNT` bundle. >>> mwntbundle = MWNTGenerator(Nwalls=5, min_wall_diameter=5, Lz=50, ... bundle_geometry='hexagon') >>> mwntbundle.save() .. image:: /images/5wall_mwnt_(1,6)@(11,7)@(18,9)@(31,2)@(41,0)_hcp_7tube_hexagon-perspective_view-01.png """
[docs] def finalize(self): """Finalize structure data by clipping region bounds if \ :attr:`~MWNT.fix_Lz` is `True`.""" # print('finalizing structure data') # print('Natoms: {}'.format(self.atoms.Natoms)) if self.fix_Lz: Lz_cutoff = self.Lz + self.bond # print('clipping_bounds') # print(self.atoms.coordinates_bounding_box) # print('Lz_cutoff: {}'.format(Lz_cutoff)) region_bounds = Cuboid(pmin=Point([-np.inf, -np.inf, 0]), pmax=Point([np.inf, np.inf, Lz_cutoff])) self.atoms.clip_bounds(region_bounds) # print('Natoms: {}'.format(self.atoms.Natoms)) super().finalize()
@classmethod
[docs] def generate_fname(cls, Ch_list=None, Nwalls=None, Ntubes=None, Lz=None, nx=None, ny=None, nz=None, bundle_geometry=None, bundle_packing=None, **kwargs): """Generate a filename string.""" # Nwalls = '{}wall_mwnt'.format(Nwalls) fname = '@'.join([str(Ch).replace(' ', '') for Ch in Ch_list]) if nx == ny == 1 and bundle_geometry is None: return fname # fname = '_'.join((Nwalls, chiralities)) # return fname packing = '{}cp'.format(bundle_packing[0]) Ntubes = '{}tube'.format(Ntubes) nx = ''.join(('{}'.format(nx), pluralize('cell', nx))) ny = ''.join(('{}'.format(ny), pluralize('cell', ny))) cells = 'x'.join((nx, ny)) if nz is not None: nz = ''.join(('{}'.format(nz), pluralize('cell', nz))) cells = 'x'.join((cells, nz)) else: cells = 'x'.join((cells, '{:.1f}Å'.format(Lz))) fname = '_'.join((fname, cells, packing)) if bundle_geometry is not None: fname = '_'.join((fname, Ntubes, bundle_geometry)) 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(Ch_list=self.Ch_list, Nwalls=self.Nwalls, Ntubes=self.Ntubes, Lz=self.Lz, nx=self.nx, ny=self.ny, nz=self.nz, bundle_geometry=self.bundle_geometry, bundle_packing=self.bundle_packing) super().save(fname=fname, outpath=outpath, structure_format=structure_format, center_centroid=center_centroid, **kwargs)