Source code for sknano.apps.nanogen_gui.nanogen_models

# -*- coding: utf-8 -*-
"""
========================================================================
NanoGen model classes (:mod:`sknano.apps.nanogen_gui.nanogen_models`)
========================================================================

.. currentmodule:: sknano.apps.nanogen_gui.nanogen_models

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

from sknano.core.refdata import aCC, element_data
from sknano.core.structures import compute_Lx, compute_Ly, compute_Lz, \
    compute_Ch, compute_T, SWNT, MWNT, Graphene, \
    UnrolledSWNT, Fullerene

_r_CC_vdw = element_data['C']['VanDerWaalsRadius']

__all__ = ['NanoGenModel', 'SWNTModel', 'MWNTModel',
           'GrapheneModel', 'FullereneModel',
           'BulkStructureModel', 'ObserverModelMixin']


[docs]class ObserverModelMixin:
[docs] def register_observer(self, observer): self._observers.append(observer)
[docs] def remove_observer(self, observer): self._observers.remove(observer)
[docs] def notify_observers(self): for observer in self._observers[:]: observer.update_app_view()
[docs]class NanoGenModel(ObserverModelMixin): """:mod:`~sknano.apps.nanogen_gui` MVC model class.""" def __init__(self): self._observers = [] self.notify_observers()
class GeneratorModelBase(ObserverModelMixin): def __init__(self): self._observers = [] self._bond = aCC self._element1 = self._element2 = 'C' @property def basis(self): return [self.element1, self.element2] @property def bond(self): return self._bond @bond.setter def bond(self, value): self._bond = value self.notify_observers() @property def element1(self): return self._element1 @element1.setter def element1(self, value): self._element1 = value self.notify_observers() @property def element2(self): return self._element2 @element2.setter def element2(self, value): self._element2 = value self.notify_observers() class SWNTModelMixin: @property def Ch(self): """Chiral indices :math:`(n, m)`""" return self.n, self.m @property def n(self): """Chiral index :math:`n`""" # return self._n return self.structure.n @n.setter def n(self, value): # self._n = value # self.structure.n = self.n self.structure.n = value self.notify_observers() @property def m(self): """Chiral index :math:`m`""" # return self._m return self.structure.m @m.setter def m(self, value): # self._m = value # self.structure.m = self.m self.structure.m = value self.notify_observers() @property def Lz(self): return compute_Lz(self.Ch, nz=self.nz, bond=self.bond) @Lz.setter def Lz(self, value): nz = 10 * value / compute_T(self.Ch, bond=self.bond, length=True) if not self.structure.fix_Lz: nz = int(nz) self.structure.nz = nz self.notify_observers() @property def nz(self): # return self._nz return self.structure.nz @nz.setter def nz(self, value): # self._nz = value # self.structure.nz = self.nz self.structure.nz = value self.notify_observers() @property def fix_Lz(self): return self.structure.fix_Lz @fix_Lz.setter def fix_Lz(self, value): self.structure.fix_Lz = value self.notify_observers() class MWNTModelMixin: @property def Lz(self): return self.structure.Lz @Lz.setter def Lz(self, value): # self._Lz = value # self.structure.Lz = self.Lz self.structure.Lz = value self.notify_observers() class BundleModelMixin: @property def Lx(self): return compute_Lx(self.Ch, nx=self.nx, bond=self.bond, gutter=_r_CC_vdw) @property def Ly(self): return compute_Ly(self.Ch, ny=self.ny, bond=self.bond, gutter=_r_CC_vdw) @property def nx(self): # return self._nx return self.structure.nx @nx.setter def nx(self, value): # self._nx = value # self.structure.nx = self.nx self.structure.nx = value self.notify_observers() @property def ny(self): # return self._ny return self.structure.ny @ny.setter def ny(self, value): # self._ny = value # self.structure.ny = self.ny self.structure.ny = value self.notify_observers()
[docs]class SWNTModel(GeneratorModelBase, SWNTModelMixin, BundleModelMixin): def __init__(self): super().__init__() # self._n = self._m = 10 self.structure = SWNT((10, 10), basis=self.basis, bond=self.bond, nx=1, ny=1, nz=1, bundle_packing='hcp') self.notify_observers()
[docs]class MWNTModel(GeneratorModelBase, MWNTModelMixin, BundleModelMixin): def __init__(self): super().__init__() self.structure = \ MWNT(Ch_list=None, Nwalls=3, min_wall_diameter=5, max_wall_diameter=100, wall_spacing=2 * _r_CC_vdw, basis=self.basis, bond=self.bond, nx=1, ny=1, Lz=1, bundle_packing='hcp') self.notify_observers() @property def Ch(self): return self.Ch_list[-1] @property def Ch_list(self): # return self._Ch_list return self.structure.Ch_list @Ch_list.setter def Ch_list(self, value): # self._Ch_list = value # self.structure.Ch_list = self.Ch_list self.structure.Ch_list = value self.notify_observers() @property def chiral_types(self): return self.structure.chiral_types @chiral_types.setter def chiral_types(self, value): self.structure.chiral_types = value self.notify_observers() @property def Nwalls(self): return self.structure.Nwalls @Nwalls.setter def Nwalls(self, value): self.structure.Nwalls = value self.notify_observers() @property def min_wall_diameter(self): return self.structure.min_wall_diameter @min_wall_diameter.setter def min_wall_diameter(self, value): self.structure.min_wall_diameter = value self.notify_observers() @property def max_wall_diameter(self): return self.structure.max_wall_diameter @max_wall_diameter.setter def max_wall_diameter(self, value): self.structure.max_wall_diameter = value self.notify_observers() @property def wall_spacing(self): return self.structure.wall_spacing @wall_spacing.setter def wall_spacing(self, value): self.structure.wall_spacing = value self.notify_observers()
# def generate_Ch_list(self): # self.structure = \ # MWNT(Nwalls=self.structure.Nwalls, # min_wall_diameter=self.structure.min_wall_diameter, # max_wall_diameter=self.structure.max_wall_diameter, # wall_spacing=self.structure.wall_spacing) class UnrolledSWNTModelMixin(SWNTModelMixin): @property def Lx(self): # return self.nx * compute_Ch(self.Ch, bond=self.bond) / 10 return self.structure.Lx @Lx.setter def Lx(self, value): # self._nx = 10 * value / compute_Ch(self.Ch, bond=self.bond) # self.structure.nx = self.nx self.structure.nx = 10 * value / compute_Ch(self.Ch, bond=self.bond) self.notify_observers() @property def nx(self): # return self._nx return self.structure.nx @nx.setter def nx(self, value): # self._nx = value # self.structure.nx = self.nx self.structure.nx = value self.notify_observers()
[docs]class GrapheneModel(GeneratorModelBase, UnrolledSWNTModelMixin): def __init__(self): super().__init__() self.conventional_cell_graphene = \ Graphene.from_conventional_cell(armchair_edge_length=1, zigzag_edge_length=1, basis=self.basis, bond=self.bond) self.primitive_cell_graphene = \ Graphene.from_primitive_cell(edge_length=1, basis=self.basis, bond=self.bond) # self._n = self._m = 10 self.structure = UnrolledSWNT((10, 10), basis=self.basis, bond=self.bond, nx=1, nz=1) self.nlayers = 1 self.layer_rotation_increment = 0.0 self.notify_observers() @property def armchair_edge_length(self): return self.conventional_cell_graphene.armchair_edge_length @armchair_edge_length.setter def armchair_edge_length(self, value): self.conventional_cell_graphene.armchair_edge_length = value self.notify_observers() @property def zigzag_edge_length(self): return self.conventional_cell_graphene.zigzag_edge_length @zigzag_edge_length.setter def zigzag_edge_length(self, value): self.conventional_cell_graphene.zigzag_edge_length = value self.notify_observers() @property def edge_length(self): return self.primitive_cell_graphene.edge_length @edge_length.setter def edge_length(self, value): self.primitive_cell_graphene.edge_length = value self.notify_observers() @property def nlayers(self): return self._nlayers @nlayers.setter def nlayers(self, value): self._nlayers = value # self.graphene.nlayers = self.structure.nlayers = self.nlayers self.notify_observers() @property def layer_rotation_increment(self): return self._layer_rotation_increment @layer_rotation_increment.setter def layer_rotation_increment(self, value): self._layer_rotation_increment = value self.notify_observers()
[docs]class FullereneModel(ObserverModelMixin): def __init__(self): self._observers = [] super().__init__() self.structure = Fullerene() self.notify_observers() @property def fullerenes(self): return self.structure.fullerenes
[docs]class BulkStructureModel(ObserverModelMixin): pass