Source code for sknano.structures._nanotube_bundle

# -*- coding: utf-8 -*-
"""
==============================================================================
Nanotube bundle base class (:mod:`sknano.structures._nanotube_bundle`)
==============================================================================

.. currentmodule:: sknano.structures._nanotube_bundle

"""
from __future__ import absolute_import, division, print_function
from six.moves import range
__docformat__ = 'restructuredtext en'

import numbers
import numpy as np

from sknano.core.math import Vector
from sknano.core.refdata import dVDW

__all__ = ['NanotubeBundleBase']


[docs]class NanotubeBundleBase(object): """Nanotube bundle structure base class.""" def __init__(self, nx=1, ny=1, Lx=None, Ly=None, vdw_spacing=dVDW, bundle_packing=None, bundle_geometry=None, **kwargs): super(NanotubeBundleBase, self).__init__(**kwargs) self.nx = nx self.ny = ny self.r1 = Vector() self.r2 = Vector() self.vdw_spacing = vdw_spacing self.bundle_geometry = bundle_geometry self._bundle_packing = bundle_packing self.bundle_coords = [] self.compute_bundle_params()
[docs] def compute_bundle_params(self): """Compute/update nanotube bundle parameters.""" self.r1.x = self.dt + self.vdw_spacing if self.bundle_packing is None and \ self.bundle_geometry in ('square', 'rectangle'): self._bundle_packing = 'ccp' elif self.bundle_packing is None and \ self.bundle_geometry in ('triangle', 'hexagon'): self._bundle_packing = 'hcp' if self.bundle_packing in ('cubic', 'ccp'): self.r2.y = self.r1.x else: self.r2.x = self.r1.x * np.cos(2 * np.pi / 3) self.r2.y = self.r1.x * np.sin(2 * np.pi / 3) if self.bundle_packing is None: self._bundle_packing = 'hcp' if self.bundle_geometry == 'hexagon': nrows = max(self.nx, self.ny, 3) if nrows % 2 != 1: nrows += 1 ntubes_per_end_rows = int((nrows + 1) / 2) row = 0 ntubes_per_row = nrows while ntubes_per_row >= ntubes_per_end_rows: if row == 0: for n in range(ntubes_per_row): dr = n * self.r1 self.bundle_coords.append(dr) else: for nx in range(ntubes_per_row): for ny in (-row, row): dr = Vector() dr.x = abs(ny * self.r2.x) dr.y = ny * self.r2.y dr = nx * self.r1 + dr self.bundle_coords.append(dr) row += 1 ntubes_per_row = nrows - row elif self.bundle_geometry == 'rectangle': Lx = 10 * self.Lx for nx in range(self.nx): for ny in range(self.ny): dr = nx * self.r1 + ny * self.r2 while dr.x < 0: dr.x += Lx self.bundle_coords.append(dr) elif self.bundle_geometry == 'square': pass elif self.bundle_geometry == 'triangle': pass else: for nx in range(self.nx): for ny in range(self.ny): dr = nx * self.r1 + ny * self.r2 self.bundle_coords.append(dr)
@property def nx(self): """Number of nanotubes along the :math:`x`-axis.""" return self._nx @nx.setter def nx(self, value): """Set :math:`n_x`""" if not (isinstance(value, numbers.Number) or value > 0): raise TypeError('Expected a positive integer.') self._nx = int(value) @nx.deleter def nx(self): del self._nx @property def ny(self): """Number of nanotubes along the :math:`y`-axis.""" return self._ny @ny.setter def ny(self, value): """Set :math:`n_y`""" if not (isinstance(value, numbers.Number) or value > 0): raise TypeError('Expected a positive integer.') self._ny = int(value) @ny.deleter def ny(self): del self._ny @property def Lx(self): return self.nx * (self.dt + self.vdw_spacing) / 10 @property def Ly(self): return self.ny * (self.dt + self.vdw_spacing) / 10 @property def bundle_packing(self): return self._bundle_packing @bundle_packing.setter def bundle_packing(self, value): if value not in ('ccp', 'hcp'): raise ValueError('Expected value to be `hcp` or `ccp`') self._bundle_packing = value self.compute_bundle_params() @bundle_packing.deleter def bundle_packing(self): del self._bundle_packing @property def bundle_mass(self): return self.Ntubes * self.tube_mass @property def Natoms_per_bundle(self): return self.Ntubes * self.Natoms_per_tube @property def Ntubes(self): return len(self.bundle_coords)