Statistiques
| Révision :

root / ase / gui / nanotube.py @ 19

Historique | Voir | Annoter | Télécharger (5,37 ko)

1
# encoding: utf-8
2
"""nanotube.py - Window for setting up Carbon nanotubes and similar tubes.
3
"""
4

    
5
import gtk
6
from ase.gui.widgets import pack, cancel_apply_ok, oops
7
from ase.gui.setupwindow import SetupWindow
8
from ase.gui.pybutton import PyButton
9
from ase.structure import nanotube
10
import ase
11
import numpy as np
12

    
13
introtext = """\
14
Set up a Carbon nanotube by specifying the (n,m) roll-up vector.
15
Please note that m <= n.
16

17
Nanotubes of other elements can be made by specifying the element
18
and bond length.\
19
"""
20

    
21
py_template = """
22
from ase.structure import nanotube
23

24
atoms = nanotube(%(n)i, %(m)i, length=%(length)i, bond=%(bl).3f, symbol=%(symb)s)
25
"""
26

    
27

    
28
class SetupNanotube(SetupWindow):
29
    "Window for setting up a (Carbon) nanotube."
30
    def __init__(self, gui):
31
        SetupWindow.__init__(self)
32
        self.set_title("Nanotube")
33
        vbox = gtk.VBox()
34

    
35
        # Intoductory text
36
        self.packtext(vbox, introtext)
37
           
38
        # Choose the element and bond length
39
        label1 = gtk.Label("Element: ")
40
        #label.set_alignment(0.0, 0.2)
41
        self.element = gtk.Entry(max=3)
42
        self.element.set_text("C")
43
        self.element.connect('activate', self.update_element)
44
        self.bondlength = gtk.Adjustment(1.42, 0.0, 1000.0, 0.01)
45
        label2 = gtk.Label("  Bond length: ")
46
        label3 = gtk.Label("Å")
47
        bond_box = gtk.SpinButton(self.bondlength, 10.0, 3)
48
        pack(vbox, [label1, self.element, label2, bond_box, label3])
49
        self.elementinfo = gtk.Label("")
50
        self.elementinfo.modify_fg(gtk.STATE_NORMAL,
51
                                   gtk.gdk.color_parse('#FF0000'))
52
        pack(vbox, [self.elementinfo])
53
        pack(vbox, gtk.Label(""))
54

    
55
        # Choose the structure.
56
        pack(vbox, [gtk.Label("Select roll-up vector (n,m) and tube length:")])
57
        label1 = gtk.Label("n: ")
58
        label2 = gtk.Label("  m: ")
59
        self.n = gtk.Adjustment(6, 1, 100, 1)
60
        self.m = gtk.Adjustment(0, 0, 100, 1)
61
        spinn = gtk.SpinButton(self.n, 0, 0)
62
        spinm = gtk.SpinButton(self.m, 0, 0)
63
        label3 = gtk.Label("  Length: ")
64
        self.length = gtk.Adjustment(1, 1, 100, 1)
65
        spinl = gtk.SpinButton(self.length, 0, 0)
66
        pack(vbox, [label1, spinn, label2, spinm, label3, spinl])
67
        self.err = gtk.Label("")
68
        self.err.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#FF0000'))
69
        pack(vbox, [self.err])
70
        pack(vbox, gtk.Label(""))
71
        self.n.connect('value-changed', self.update_n)
72
        self.m.connect('value-changed', self.update_m)
73

    
74
        # Buttons
75
        self.pybut = PyButton("Creating a nanoparticle.")
76
        self.pybut.connect('clicked', self.makeatoms)
77
        buts = cancel_apply_ok(cancel=lambda widget: self.destroy(),
78
                               apply=self.apply,
79
                               ok=self.ok)
80
        pack(vbox, [self.pybut, buts], end=True, bottom=True)
81

    
82
        # Finalize setup
83
        self.add(vbox)
84
        vbox.show()
85
        self.show()
86
        self.gui = gui
87

    
88
    def update_n(self, *args):
89
        if self.m.value > self.n.value:
90
            self.m.value = self.n.value
91
            self.err.set_text("m decreased! (m may not be larger than n.)")
92
        else:
93
            self.err.set_text("")
94
            
95
    def update_m(self, *args):
96
        if self.m.value > self.n.value:
97
            self.n.value = self.m.value
98
            self.err.set_text("n increased! (m may not be larger than n.)")
99
        else:
100
            self.err.set_text("")
101

    
102
    def update_element(self, *args):
103
        "Called when a new element may have been entered."
104
        # Assumes the element widget is self.element and that a label
105
        # for errors is self.elementinfo.  The chemical symbol is
106
        # placed in self.legalelement - or None if the element is
107
        # invalid.
108
        elem = self.element.get_text()
109
        if not elem:
110
            self.invalid_element("  No element specified!")
111
            return False
112
        try:
113
            z = int(elem)
114
        except ValueError:
115
            # Probably a symbol
116
            try:
117
                z = ase.data.atomic_numbers[elem]
118
            except KeyError:
119
                self.invalid_element()
120
                return False
121
        try:
122
            symb = ase.data.chemical_symbols[z]
123
        except KeyError:
124
            self.invalid_element()
125
            return False
126
        self.elementinfo.set_text("")
127
        self.legal_element = symb
128
        return True
129
        
130
    def makeatoms(self, *args):
131
        self.update_element()
132
        if self.legal_element is None:
133
            self.atoms = None
134
            self.pybut.python = None
135
        else:
136
            n = int(self.n.value)
137
            m = int(self.m.value)
138
            symb = self.legal_element
139
            length = int(self.length.value)
140
            bl = self.bondlength.value
141
            self.atoms = nanotube(n, m, length=length, bond=bl, symbol=symb)
142
            self.pybut.python = py_template % {'n': n, 'm':m, 'length':length,
143
                                               'symb':symb, 'bl':bl}
144
        
145

    
146
    def apply(self, *args):
147
        self.makeatoms()
148
        if self.atoms is not None:
149
            self.gui.new_atoms(self.atoms)
150
            return True
151
        else:
152
            oops("No valid atoms.",
153
                 "You have not (yet) specified a consistent set of parameters.")
154
            return False
155

    
156
    def ok(self, *args):
157
        if self.apply():
158
            self.destroy()
159
            
160