Statistiques
| Révision :

root / ase / gui / minimize.py @ 16

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