Statistiques
| Révision :

root / ase / gui / graphene.py @ 3

Historique | Voir | Annoter | Télécharger (8,69 ko)

1
# encoding: utf-8
2
"""nanotube.py - Window for setting up Graphene sheets and ribbons.
3
"""
4

    
5

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

    
14
introtext = """\
15
Set up a graphene sheet or a graphene nanoribbon.  A nanoribbon may
16
optionally be saturated with hydrogen (or another element).\
17
"""
18

    
19
py_template = """
20
from ase.structure import nanotube
21

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

    
25
class SetupGraphene(SetupWindow):
26
    "Window for setting up a graphene sheet or nanoribbon."
27
    def __init__(self, gui):
28
        SetupWindow.__init__(self)
29
        self.set_title("Nanotube")
30
        vbox = gtk.VBox()
31

    
32
        # Intoductory text
33
        self.packtext(vbox, introtext)
34

    
35
        # Choose structure
36
        label = gtk.Label("Structure: ")
37
        self.struct = gtk.combo_box_new_text()
38
        for s in ("Infinite sheet", "Unsaturated ribbon", "Saturated ribbon"):
39
            self.struct.append_text(s)
40
        self.struct.set_active(0)
41
        self.struct.connect('changed', self.update_gui)
42
        pack(vbox, [label, self.struct])
43

    
44
        # Orientation
45
        label = gtk.Label("Orientation: ")
46
        self.orient = gtk.combo_box_new_text()
47
        self.orient_text = []
48
        for s in ("zigzag", "armchair"):
49
            self.orient.append_text(s)
50
            self.orient_text.append(s)
51
        self.orient.set_active(0)
52
        self.orient.connect('changed', self.update_gui)
53
        pack(vbox, [label, self.orient])
54
        pack(vbox, gtk.Label(""))
55

    
56

    
57
        # Choose the element and bond length
58
        label1 = gtk.Label("Element: ")
59
        #label.set_alignment(0.0, 0.2)
60
        self.element = gtk.Entry(max=3)
61
        self.element.set_text("C")
62
        self.element.connect('activate', self.update_element)
63
        self.bondlength = gtk.Adjustment(1.42, 0.0, 1000.0, 0.01)
64
        label2 = gtk.Label("  Bond length: ")
65
        label3 = gtk.Label("Å")
66
        bond_box = gtk.SpinButton(self.bondlength, 10.0, 3)
67
        pack(vbox, [label1, self.element, label2, bond_box, label3])
68

    
69
        # Choose the saturation element and bond length
70
        self.sat_label1 = gtk.Label("Saturation: ")
71
        #label.set_alignment(0.0, 0.2)
72
        self.element2 = gtk.Entry(max=3)
73
        self.element2.set_text("H")
74
        self.element2.connect('activate', self.update_element)
75
        self.bondlength2 = gtk.Adjustment(1.12, 0.0, 1000.0, 0.01)
76
        self.sat_label2 = gtk.Label("  Bond length: ")
77
        self.sat_label3 = gtk.Label("Å")
78
        self.bond_box = gtk.SpinButton(self.bondlength2, 10.0, 3)
79
        pack(vbox, [self.sat_label1, self.element2, self.sat_label2,
80
                    self.bond_box, self.sat_label3])
81

    
82
        self.elementinfo = gtk.Label("")
83
        self.elementinfo.modify_fg(gtk.STATE_NORMAL,
84
                                   gtk.gdk.color_parse('#FF0000'))
85
        pack(vbox, [self.elementinfo])
86
        pack(vbox, gtk.Label(""))
87

    
88
        # Size
89
        label1 = gtk.Label("Width: ")
90
        label2 = gtk.Label("  Length: ")
91
        self.n = gtk.Adjustment(1, 1, 100, 1)
92
        self.m = gtk.Adjustment(1, 1, 100, 1)
93
        spinn = gtk.SpinButton(self.n, 0, 0)
94
        spinm = gtk.SpinButton(self.m, 0, 0)
95
        pack(vbox, [label1, spinn, label2, spinm])
96

    
97
        # Vacuum
98
        label1 = gtk.Label("Vacuum: ")
99
        self.vacuum = gtk.Adjustment(5.0, 0.0, 1000.0, 0.1)
100
        label2 = gtk.Label("Å")
101
        vac_box = gtk.SpinButton(self.vacuum, 10.0, 2)
102
        pack(vbox, [label1, vac_box, label2])
103
        pack(vbox, gtk.Label(""))
104

    
105

    
106
        # Buttons
107
        #self.pybut = PyButton("Creating a nanoparticle.")
108
        #self.pybut.connect('clicked', self.makeatoms)
109
        buts = cancel_apply_ok(cancel=lambda widget: self.destroy(),
110
                               apply=self.apply,
111
                               ok=self.ok)
112
        pack(vbox, [buts], end=True, bottom=True)
113

    
114
        # Finalize setup
115
        self.update_gui()
116
        self.add(vbox)
117
        vbox.show()
118
        self.show()
119
        self.gui = gui
120

    
121
    def update_element(self, *args):
122
        "Called when a new element may have been entered."
123
        # Assumes the element widget is self.element and that a label
124
        # for errors is self.elementinfo.  The chemical symbol is
125
        # placed in self.legalelement - or None if the element is
126
        # invalid.
127
        symb = []
128
        if self.struct.get_active() == 2:
129
            # Saturated nanoribbon
130
            elements = (self.element.get_text(), self.element2.get_text())
131
        else:
132
            elements = (self.element.get_text(), )
133
            
134
        for elem in elements:
135
            if not elem:
136
                self.invalid_element("  No element specified!")
137
                return False
138
            try:
139
                z = int(elem)
140
            except ValueError:
141
                # Probably a symbol
142
                try:
143
                    z = ase.data.atomic_numbers[elem]
144
                except KeyError:
145
                    self.invalid_element()
146
                    return False
147
            try:
148
                symb.append(ase.data.chemical_symbols[z])
149
            except KeyError:
150
                self.invalid_element()
151
                return False
152
        self.elementinfo.set_text("")
153
        self.legal_element = symb[0]
154
        if len(symb) == 2:
155
            self.legal_element2 = symb[1]
156
        else:
157
            self.legal_element2 = None
158
        return True
159
        
160
    def update_gui(self, *args):
161
        # Saturation element is only relevant for saturated nanoribbons
162
        satur = self.struct.get_active() == 2
163
        for w in (self.element2, self.bond_box):
164
            w.set_sensitive(satur)
165
        # Infinite zigzag sheets must have even width
166
        if self.struct.get_active() == 0 and self.orient.get_active() == 0:
167
            if self.n.value % 2 == 1:
168
                self.n.value += 1
169
            self.n.lower = 2
170
            self.n.step_increment = 2
171
        else:
172
            self.n.lower = 1
173
            self.n.step_increment = 1
174
        
175
    def makeatoms(self, *args):
176
        self.update_element()
177
        if self.legal_element is None or (self.struct.get_active() == 2 and
178
                                          self.legal_element2 is None):
179
            self.atoms = None
180
            self.pybut.python = None
181
        else:
182
            n = int(self.n.value)
183
            m = int(self.m.value)
184
            CC = self.bondlength.value
185
            vacuum = self.vacuum.value
186
            orient = self.orient_text[self.orient.get_active()]
187
            elem = self.legal_element
188
            if self.struct.get_active() == 0:
189
                # Extended sheet
190
                self.atoms = graphene_nanoribbon(n, m, type=orient, C_C=CC,
191
                                                 vacc=vacuum, sheet=True,
192
                                                 main_element=elem)
193
            elif self.struct.get_active() == 1:
194
                # Unsaturated nanoribbon
195
                self.atoms = graphene_nanoribbon(n, m, type=orient, C_C=CC,
196
                                                 vacc=vacuum,
197
                                                 main_element=elem)
198
            elif self.struct.get_active() == 2:
199
                # Saturated nanoribbon
200
                elem2 = self.legal_element2
201
                self.atoms = graphene_nanoribbon(n, m, type=orient, C_C=CC,
202
                                                 C_H=self.bondlength2.value,
203
                                                 vacc=vacuum,
204
                                                 saturated=True,
205
                                                 main_element=elem,
206
                                                 satur_element=elem2)
207
            else:
208
                raise RuntimeError("Unknown structure in SetupGraphene!")
209
        # Now, rotate into the xy plane (ase.gui's default view plane)
210
        pos = self.atoms.get_positions()
211
        cell = self.atoms.get_cell()
212
        pbc = self.atoms.get_pbc()
213
        cell[1,1], cell[2,2] = cell[2,2], cell[1,1]
214
        x = pos[:,1].copy()
215
        z = pos[:,2].copy()
216
        pos[:,1] = z
217
        pos[:,2] = x
218
        self.atoms.set_cell(cell)
219
        self.atoms.set_positions(pos)
220
        self.atoms.set_pbc([pbc[0], pbc[2], pbc[1]])
221

    
222
    def apply(self, *args):
223
        self.makeatoms()
224
        if self.atoms is not None:
225
            self.gui.new_atoms(self.atoms)
226
            return True
227
        else:
228
            oops("No valid atoms.",
229
                 "You have not (yet) specified a consistent set of parameters.")
230
            return False
231

    
232
    def ok(self, *args):
233
        if self.apply():
234
            self.destroy()
235
            
236
            
237