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