root / ase / gui / minimize.py @ 1
Historique | Voir | Annoter | Télécharger (4,39 ko)
1 |
# encoding: utf-8
|
---|---|
2 |
|
3 |
"Module for performing energy minimization."
|
4 |
|
5 |
import gtk |
6 |
from ase.gui.simulation import Simulation |
7 |
from ase.gui.widgets import oops, pack, AseGuiCancelException |
8 |
import ase |
9 |
import numpy as np |
10 |
|
11 |
class MinimizeMixin: |
12 |
minimizers = ('BFGS', 'BFGSLineSearch', 'LBFGS', 'LBFGSLineSearch', 'MDMin', 'FIRE') |
13 |
def make_minimize_gui(self, box): |
14 |
self.algo = gtk.combo_box_new_text()
|
15 |
for m in self.minimizers: |
16 |
self.algo.append_text(m)
|
17 |
self.algo.set_active(0) |
18 |
pack(box, [gtk.Label("Algorithm: "), self.algo]) |
19 |
|
20 |
self.fmax = gtk.Adjustment(0.05, 0.00, 10.0, 0.01) |
21 |
self.fmax_spin = gtk.SpinButton(self.fmax, 0, 3) |
22 |
lbl = gtk.Label() |
23 |
lbl.set_markup("Convergence criterion: F<sub>max</sub> = ")
|
24 |
pack(box, [lbl, self.fmax_spin])
|
25 |
|
26 |
self.steps = gtk.Adjustment(100, 1, 1000000, 1) |
27 |
self.steps_spin = gtk.SpinButton(self.steps, 0, 0) |
28 |
pack(box, [gtk.Label("Max. number of steps: "), self.steps_spin]) |
29 |
|
30 |
class Minimize(Simulation, MinimizeMixin): |
31 |
"Window for performing energy minimization."
|
32 |
|
33 |
def __init__(self, gui): |
34 |
Simulation.__init__(self, gui)
|
35 |
self.set_title("Energy minimization") |
36 |
|
37 |
vbox = gtk.VBox() |
38 |
self.packtext(vbox,
|
39 |
"Minimize the energy with respect to the positions.")
|
40 |
self.packimageselection(vbox)
|
41 |
pack(vbox, gtk.Label(""))
|
42 |
|
43 |
self.make_minimize_gui(vbox)
|
44 |
|
45 |
pack(vbox, gtk.Label(""))
|
46 |
self.status_label = gtk.Label("") |
47 |
pack(vbox, [self.status_label])
|
48 |
self.makebutbox(vbox)
|
49 |
vbox.show() |
50 |
self.add(vbox)
|
51 |
self.show()
|
52 |
self.gui.register_vulnerable(self) |
53 |
|
54 |
def run(self, *args): |
55 |
"User has pressed [Run]: run the minimization."
|
56 |
if not self.setup_atoms(): |
57 |
return
|
58 |
fmax = self.fmax.value
|
59 |
steps = self.steps.value
|
60 |
mininame = self.minimizers[self.algo.get_active()] |
61 |
self.begin(mode="min", algo=mininame, fmax=fmax, steps=steps) |
62 |
algo = getattr(ase.optimize, mininame)
|
63 |
try:
|
64 |
logger_func = self.gui.simulation['progress'].get_logger_stream |
65 |
except (KeyError, AttributeError): |
66 |
logger = None
|
67 |
else:
|
68 |
logger = logger_func() # Don't catch errors in the function.
|
69 |
|
70 |
# Display status message
|
71 |
self.status_label.set_text("Running ...") |
72 |
self.status_label.modify_fg(gtk.STATE_NORMAL,
|
73 |
gtk.gdk.color_parse('#AA0000'))
|
74 |
while gtk.events_pending():
|
75 |
gtk.main_iteration() |
76 |
|
77 |
self.prepare_store_atoms()
|
78 |
minimizer = algo(self.atoms, logfile=logger)
|
79 |
minimizer.attach(self.store_atoms)
|
80 |
try:
|
81 |
minimizer.run(fmax=fmax, steps=steps) |
82 |
except AseGuiCancelException:
|
83 |
# Update display to reflect cancellation of simulation.
|
84 |
self.status_label.set_text("Minimization CANCELLED after %i steps." |
85 |
% (self.count_steps,))
|
86 |
self.status_label.modify_fg(gtk.STATE_NORMAL,
|
87 |
gtk.gdk.color_parse('#AA4000'))
|
88 |
except MemoryError: |
89 |
self.status_label.set_text("Out of memory, consider using LBFGS instead") |
90 |
self.status_label.modify_fg(gtk.STATE_NORMAL,
|
91 |
gtk.gdk.color_parse('#AA4000'))
|
92 |
|
93 |
else:
|
94 |
# Update display to reflect succesful end of simulation.
|
95 |
self.status_label.set_text("Minimization completed in %i steps." |
96 |
% (self.count_steps,))
|
97 |
self.status_label.modify_fg(gtk.STATE_NORMAL,
|
98 |
gtk.gdk.color_parse('#007700'))
|
99 |
|
100 |
self.end()
|
101 |
if self.count_steps: |
102 |
# Notify other windows that atoms have changed.
|
103 |
# This also notifies this window!
|
104 |
self.gui.notify_vulnerable()
|
105 |
|
106 |
# Open movie window and energy graph
|
107 |
if self.gui.images.nimages > 1: |
108 |
self.gui.movie()
|
109 |
assert not np.isnan(self.gui.images.E[0]) |
110 |
if not self.gui.plot_graphs_newatoms(): |
111 |
expr = 'i, e - E[-1]'
|
112 |
self.gui.plot_graphs(expr=expr)
|
113 |
|
114 |
def notify_atoms_changed(self): |
115 |
"When atoms have changed, check for the number of images."
|
116 |
self.setupimageselection()
|
117 |
|