Statistiques
| Révision :

root / ase / gui / graphene.py @ 13

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

1 1 tkerber
# encoding: utf-8
2 1 tkerber
"""nanotube.py - Window for setting up Graphene sheets and ribbons.
3 1 tkerber
"""
4 1 tkerber
5 1 tkerber
6 1 tkerber
import gtk
7 1 tkerber
from ase.gui.widgets import pack, cancel_apply_ok, oops
8 1 tkerber
from ase.gui.setupwindow import SetupWindow
9 1 tkerber
from ase.gui.pybutton import PyButton
10 1 tkerber
from ase.structure import graphene_nanoribbon
11 1 tkerber
import ase
12 1 tkerber
import numpy as np
13 1 tkerber
14 1 tkerber
introtext = """\
15 1 tkerber
Set up a graphene sheet or a graphene nanoribbon.  A nanoribbon may
16 1 tkerber
optionally be saturated with hydrogen (or another element).\
17 1 tkerber
"""
18 1 tkerber
19 1 tkerber
py_template = """
20 1 tkerber
from ase.structure import nanotube
21 1 tkerber

22 1 tkerber
atoms = nanotube(%(n)i, %(m)i, length=%(length)i, bond=%(bl).3f, symbol=%(symb)s)
23 1 tkerber
"""
24 1 tkerber
25 1 tkerber
class SetupGraphene(SetupWindow):
26 1 tkerber
    "Window for setting up a graphene sheet or nanoribbon."
27 1 tkerber
    def __init__(self, gui):
28 1 tkerber
        SetupWindow.__init__(self)
29 1 tkerber
        self.set_title("Nanotube")
30 1 tkerber
        vbox = gtk.VBox()
31 1 tkerber
32 1 tkerber
        # Intoductory text
33 1 tkerber
        self.packtext(vbox, introtext)
34 1 tkerber
35 1 tkerber
        # Choose structure
36 1 tkerber
        label = gtk.Label("Structure: ")
37 1 tkerber
        self.struct = gtk.combo_box_new_text()
38 1 tkerber
        for s in ("Infinite sheet", "Unsaturated ribbon", "Saturated ribbon"):
39 1 tkerber
            self.struct.append_text(s)
40 1 tkerber
        self.struct.set_active(0)
41 1 tkerber
        self.struct.connect('changed', self.update_gui)
42 1 tkerber
        pack(vbox, [label, self.struct])
43 1 tkerber
44 1 tkerber
        # Orientation
45 1 tkerber
        label = gtk.Label("Orientation: ")
46 1 tkerber
        self.orient = gtk.combo_box_new_text()
47 1 tkerber
        self.orient_text = []
48 1 tkerber
        for s in ("zigzag", "armchair"):
49 1 tkerber
            self.orient.append_text(s)
50 1 tkerber
            self.orient_text.append(s)
51 1 tkerber
        self.orient.set_active(0)
52 1 tkerber
        self.orient.connect('changed', self.update_gui)
53 1 tkerber
        pack(vbox, [label, self.orient])
54 1 tkerber
        pack(vbox, gtk.Label(""))
55 1 tkerber
56 1 tkerber
57 1 tkerber
        # Choose the element and bond length
58 1 tkerber
        label1 = gtk.Label("Element: ")
59 1 tkerber
        #label.set_alignment(0.0, 0.2)
60 1 tkerber
        self.element = gtk.Entry(max=3)
61 1 tkerber
        self.element.set_text("C")
62 1 tkerber
        self.element.connect('activate', self.update_element)
63 1 tkerber
        self.bondlength = gtk.Adjustment(1.42, 0.0, 1000.0, 0.01)
64 1 tkerber
        label2 = gtk.Label("  Bond length: ")
65 1 tkerber
        label3 = gtk.Label("Å")
66 1 tkerber
        bond_box = gtk.SpinButton(self.bondlength, 10.0, 3)
67 1 tkerber
        pack(vbox, [label1, self.element, label2, bond_box, label3])
68 1 tkerber
69 1 tkerber
        # Choose the saturation element and bond length
70 1 tkerber
        self.sat_label1 = gtk.Label("Saturation: ")
71 1 tkerber
        #label.set_alignment(0.0, 0.2)
72 1 tkerber
        self.element2 = gtk.Entry(max=3)
73 1 tkerber
        self.element2.set_text("H")
74 1 tkerber
        self.element2.connect('activate', self.update_element)
75 1 tkerber
        self.bondlength2 = gtk.Adjustment(1.12, 0.0, 1000.0, 0.01)
76 1 tkerber
        self.sat_label2 = gtk.Label("  Bond length: ")
77 1 tkerber
        self.sat_label3 = gtk.Label("Å")
78 1 tkerber
        self.bond_box = gtk.SpinButton(self.bondlength2, 10.0, 3)
79 1 tkerber
        pack(vbox, [self.sat_label1, self.element2, self.sat_label2,
80 1 tkerber
                    self.bond_box, self.sat_label3])
81 1 tkerber
82 1 tkerber
        self.elementinfo = gtk.Label("")
83 1 tkerber
        self.elementinfo.modify_fg(gtk.STATE_NORMAL,
84 1 tkerber
                                   gtk.gdk.color_parse('#FF0000'))
85 1 tkerber
        pack(vbox, [self.elementinfo])
86 1 tkerber
        pack(vbox, gtk.Label(""))
87 1 tkerber
88 1 tkerber
        # Size
89 1 tkerber
        label1 = gtk.Label("Width: ")
90 1 tkerber
        label2 = gtk.Label("  Length: ")
91 1 tkerber
        self.n = gtk.Adjustment(1, 1, 100, 1)
92 1 tkerber
        self.m = gtk.Adjustment(1, 1, 100, 1)
93 1 tkerber
        spinn = gtk.SpinButton(self.n, 0, 0)
94 1 tkerber
        spinm = gtk.SpinButton(self.m, 0, 0)
95 1 tkerber
        pack(vbox, [label1, spinn, label2, spinm])
96 1 tkerber
97 1 tkerber
        # Vacuum
98 1 tkerber
        label1 = gtk.Label("Vacuum: ")
99 1 tkerber
        self.vacuum = gtk.Adjustment(5.0, 0.0, 1000.0, 0.1)
100 1 tkerber
        label2 = gtk.Label("Å")
101 1 tkerber
        vac_box = gtk.SpinButton(self.vacuum, 10.0, 2)
102 1 tkerber
        pack(vbox, [label1, vac_box, label2])
103 1 tkerber
        pack(vbox, gtk.Label(""))
104 1 tkerber
105 1 tkerber
106 1 tkerber
        # Buttons
107 1 tkerber
        #self.pybut = PyButton("Creating a nanoparticle.")
108 1 tkerber
        #self.pybut.connect('clicked', self.makeatoms)
109 1 tkerber
        buts = cancel_apply_ok(cancel=lambda widget: self.destroy(),
110 1 tkerber
                               apply=self.apply,
111 1 tkerber
                               ok=self.ok)
112 1 tkerber
        pack(vbox, [buts], end=True, bottom=True)
113 1 tkerber
114 1 tkerber
        # Finalize setup
115 1 tkerber
        self.update_gui()
116 1 tkerber
        self.add(vbox)
117 1 tkerber
        vbox.show()
118 1 tkerber
        self.show()
119 1 tkerber
        self.gui = gui
120 1 tkerber
121 1 tkerber
    def update_element(self, *args):
122 1 tkerber
        "Called when a new element may have been entered."
123 1 tkerber
        # Assumes the element widget is self.element and that a label
124 1 tkerber
        # for errors is self.elementinfo.  The chemical symbol is
125 1 tkerber
        # placed in self.legalelement - or None if the element is
126 1 tkerber
        # invalid.
127 1 tkerber
        symb = []
128 1 tkerber
        if self.struct.get_active() == 2:
129 1 tkerber
            # Saturated nanoribbon
130 1 tkerber
            elements = (self.element.get_text(), self.element2.get_text())
131 1 tkerber
        else:
132 1 tkerber
            elements = (self.element.get_text(), )
133 1 tkerber
134 1 tkerber
        for elem in elements:
135 1 tkerber
            if not elem:
136 1 tkerber
                self.invalid_element("  No element specified!")
137 1 tkerber
                return False
138 1 tkerber
            try:
139 1 tkerber
                z = int(elem)
140 1 tkerber
            except ValueError:
141 1 tkerber
                # Probably a symbol
142 1 tkerber
                try:
143 1 tkerber
                    z = ase.data.atomic_numbers[elem]
144 1 tkerber
                except KeyError:
145 1 tkerber
                    self.invalid_element()
146 1 tkerber
                    return False
147 1 tkerber
            try:
148 1 tkerber
                symb.append(ase.data.chemical_symbols[z])
149 1 tkerber
            except KeyError:
150 1 tkerber
                self.invalid_element()
151 1 tkerber
                return False
152 1 tkerber
        self.elementinfo.set_text("")
153 1 tkerber
        self.legal_element = symb[0]
154 1 tkerber
        if len(symb) == 2:
155 1 tkerber
            self.legal_element2 = symb[1]
156 1 tkerber
        else:
157 1 tkerber
            self.legal_element2 = None
158 1 tkerber
        return True
159 1 tkerber
160 1 tkerber
    def update_gui(self, *args):
161 1 tkerber
        # Saturation element is only relevant for saturated nanoribbons
162 1 tkerber
        satur = self.struct.get_active() == 2
163 1 tkerber
        for w in (self.element2, self.bond_box):
164 1 tkerber
            w.set_sensitive(satur)
165 1 tkerber
        # Infinite zigzag sheets must have even width
166 1 tkerber
        if self.struct.get_active() == 0 and self.orient.get_active() == 0:
167 1 tkerber
            if self.n.value % 2 == 1:
168 1 tkerber
                self.n.value += 1
169 1 tkerber
            self.n.lower = 2
170 1 tkerber
            self.n.step_increment = 2
171 1 tkerber
        else:
172 1 tkerber
            self.n.lower = 1
173 1 tkerber
            self.n.step_increment = 1
174 1 tkerber
175 1 tkerber
    def makeatoms(self, *args):
176 1 tkerber
        self.update_element()
177 1 tkerber
        if self.legal_element is None or (self.struct.get_active() == 2 and
178 1 tkerber
                                          self.legal_element2 is None):
179 1 tkerber
            self.atoms = None
180 1 tkerber
            self.pybut.python = None
181 1 tkerber
        else:
182 1 tkerber
            n = int(self.n.value)
183 1 tkerber
            m = int(self.m.value)
184 1 tkerber
            CC = self.bondlength.value
185 1 tkerber
            vacuum = self.vacuum.value
186 1 tkerber
            orient = self.orient_text[self.orient.get_active()]
187 1 tkerber
            elem = self.legal_element
188 1 tkerber
            if self.struct.get_active() == 0:
189 1 tkerber
                # Extended sheet
190 1 tkerber
                self.atoms = graphene_nanoribbon(n, m, type=orient, C_C=CC,
191 1 tkerber
                                                 vacc=vacuum, sheet=True,
192 1 tkerber
                                                 main_element=elem)
193 1 tkerber
            elif self.struct.get_active() == 1:
194 1 tkerber
                # Unsaturated nanoribbon
195 1 tkerber
                self.atoms = graphene_nanoribbon(n, m, type=orient, C_C=CC,
196 1 tkerber
                                                 vacc=vacuum,
197 1 tkerber
                                                 main_element=elem)
198 1 tkerber
            elif self.struct.get_active() == 2:
199 1 tkerber
                # Saturated nanoribbon
200 1 tkerber
                elem2 = self.legal_element2
201 1 tkerber
                self.atoms = graphene_nanoribbon(n, m, type=orient, C_C=CC,
202 1 tkerber
                                                 C_H=self.bondlength2.value,
203 1 tkerber
                                                 vacc=vacuum,
204 1 tkerber
                                                 saturated=True,
205 1 tkerber
                                                 main_element=elem,
206 1 tkerber
                                                 satur_element=elem2)
207 1 tkerber
            else:
208 1 tkerber
                raise RuntimeError("Unknown structure in SetupGraphene!")
209 1 tkerber
        # Now, rotate into the xy plane (ase.gui's default view plane)
210 1 tkerber
        pos = self.atoms.get_positions()
211 1 tkerber
        cell = self.atoms.get_cell()
212 1 tkerber
        pbc = self.atoms.get_pbc()
213 1 tkerber
        cell[1,1], cell[2,2] = cell[2,2], cell[1,1]
214 1 tkerber
        x = pos[:,1].copy()
215 1 tkerber
        z = pos[:,2].copy()
216 1 tkerber
        pos[:,1] = z
217 1 tkerber
        pos[:,2] = x
218 1 tkerber
        self.atoms.set_cell(cell)
219 1 tkerber
        self.atoms.set_positions(pos)
220 1 tkerber
        self.atoms.set_pbc([pbc[0], pbc[2], pbc[1]])
221 1 tkerber
222 1 tkerber
    def apply(self, *args):
223 1 tkerber
        self.makeatoms()
224 1 tkerber
        if self.atoms is not None:
225 1 tkerber
            self.gui.new_atoms(self.atoms)
226 1 tkerber
            return True
227 1 tkerber
        else:
228 1 tkerber
            oops("No valid atoms.",
229 1 tkerber
                 "You have not (yet) specified a consistent set of parameters.")
230 1 tkerber
            return False
231 1 tkerber
232 1 tkerber
    def ok(self, *args):
233 1 tkerber
        if self.apply():
234 1 tkerber
            self.destroy()
235 1 tkerber
236 1 tkerber