Statistiques
| Révision :

root / ase / optimize / test / __init__.py @ 1

Historique | Voir | Annoter | Télécharger (4,33 ko)

1 1 tkerber
"""Define a helper function for running tests
2 1 tkerber

3 1 tkerber
The skeleton for making a new setup is as follows:
4 1 tkerber

5 1 tkerber
from ase.optimize.test import run_test
6 1 tkerber

7 1 tkerber
def get_atoms():
8 1 tkerber
    return Atoms('H')
9 1 tkerber

10 1 tkerber
def get_calculator():
11 1 tkerber
    return EMT()
12 1 tkerber

13 1 tkerber
run_test(get_atoms, get_calculator, 'Hydrogen')
14 1 tkerber
"""
15 1 tkerber
import matplotlib
16 1 tkerber
matplotlib.rcParams['backend']="Agg"
17 1 tkerber
18 1 tkerber
from ase.optimize.bfgs import BFGS
19 1 tkerber
from ase.optimize.lbfgs import LBFGS, LBFGSLineSearch
20 1 tkerber
from ase.optimize.fire import FIRE
21 1 tkerber
from ase.optimize.mdmin import MDMin
22 1 tkerber
from ase.optimize.sciopt import SciPyFminCG
23 1 tkerber
from ase.optimize.sciopt import SciPyFminBFGS
24 1 tkerber
from ase.optimize.bfgslinesearch import BFGSLineSearch
25 1 tkerber
26 1 tkerber
from ase.parallel import rank, paropen
27 1 tkerber
28 1 tkerber
import matplotlib.pyplot as pl
29 1 tkerber
import numpy as np
30 1 tkerber
31 1 tkerber
import traceback
32 1 tkerber
33 1 tkerber
optimizers = [
34 1 tkerber
    'BFGS',
35 1 tkerber
    'LBFGS',
36 1 tkerber
    'LBFGSLineSearch',
37 1 tkerber
    'FIRE',
38 1 tkerber
    'MDMin',
39 1 tkerber
    'SciPyFminCG',
40 1 tkerber
    'SciPyFminBFGS',
41 1 tkerber
    'BFGSLineSearch'
42 1 tkerber
]
43 1 tkerber
44 1 tkerber
def get_optimizer(optimizer):
45 1 tkerber
    if optimizer == 'BFGS': return BFGS
46 1 tkerber
    elif optimizer == 'LBFGS': return LBFGS
47 1 tkerber
    elif optimizer == 'LBFGSLineSearch': return LBFGSLineSearch
48 1 tkerber
    elif optimizer == 'FIRE': return FIRE
49 1 tkerber
    elif optimizer == 'MDMin': return MDMin
50 1 tkerber
    elif optimizer == 'SciPyFminCG': return SciPyFminCG
51 1 tkerber
    elif optimizer == 'SciPyFminBFGS': return SciPyFminBFGS
52 1 tkerber
    elif optimizer == 'BFGSLineSearch': return BFGSLineSearch
53 1 tkerber
54 1 tkerber
def run_test(get_atoms, get_calculator, name,
55 1 tkerber
             fmax=0.05, steps=100, plot=True):
56 1 tkerber
57 1 tkerber
    plotter = Plotter(name, fmax)
58 1 tkerber
    csvwriter = CSVWriter(name)
59 1 tkerber
    for optimizer in optimizers:
60 1 tkerber
        note = ''
61 1 tkerber
        logname = name + '-' + optimizer
62 1 tkerber
63 1 tkerber
        atoms = get_atoms()
64 1 tkerber
        atoms.set_calculator(get_calculator())
65 1 tkerber
        opt = get_optimizer(optimizer)
66 1 tkerber
        relax = opt(atoms, logfile=None)
67 1 tkerber
                    #logfile = logname + '.log',
68 1 tkerber
                    #trajectory = logname + '.traj')
69 1 tkerber
70 1 tkerber
        obs = DataObserver(atoms)
71 1 tkerber
        relax.attach(obs)
72 1 tkerber
        try:
73 1 tkerber
            relax.run(fmax = fmax, steps = steps)
74 1 tkerber
            E = atoms.get_potential_energy()
75 1 tkerber
76 1 tkerber
            if relax.get_number_of_steps() == steps:
77 1 tkerber
                note = 'Not converged in %i steps' % steps
78 1 tkerber
        except Exception:
79 1 tkerber
            traceback.print_exc()
80 1 tkerber
            note = 'An exception occurred'
81 1 tkerber
            E = np.nan
82 1 tkerber
83 1 tkerber
        nsteps = relax.get_number_of_steps()
84 1 tkerber
        if hasattr(relax, 'force_calls'):
85 1 tkerber
            fc = relax.force_calls
86 1 tkerber
            if rank == 0:
87 1 tkerber
                print '%-15s %-15s %3i %8.3f (%3i) %s' % (name, optimizer, nsteps, E, fc, note)
88 1 tkerber
        else:
89 1 tkerber
            fc = nsteps
90 1 tkerber
            if rank == 0:
91 1 tkerber
                print '%-15s %-15s %3i %8.3f       %s' % (name, optimizer, nsteps, E, note)
92 1 tkerber
93 1 tkerber
        plotter.plot(optimizer, obs.get_E(), obs.get_fmax())
94 1 tkerber
        csvwriter.write(optimizer, nsteps, E, fc, note)
95 1 tkerber
96 1 tkerber
    plotter.save()
97 1 tkerber
    csvwriter.finalize()
98 1 tkerber
99 1 tkerber
class Plotter:
100 1 tkerber
    def __init__(self, name, fmax):
101 1 tkerber
        self.name = name
102 1 tkerber
        self.fmax = fmax
103 1 tkerber
        if rank == 0:
104 1 tkerber
            self.fig = pl.figure(figsize=[12.0, 9.0])
105 1 tkerber
            self.axes0 = self.fig.add_subplot(2, 1, 1)
106 1 tkerber
            self.axes1 = self.fig.add_subplot(2, 1, 2)
107 1 tkerber
108 1 tkerber
    def plot(self, optimizer, E, fmax):
109 1 tkerber
        if rank == 0:
110 1 tkerber
            self.axes0.plot(E, label = optimizer)
111 1 tkerber
            self.axes1.plot(fmax)
112 1 tkerber
113 1 tkerber
    def save(self, format='png'):
114 1 tkerber
        if rank == 0:
115 1 tkerber
            self.axes0.legend()
116 1 tkerber
            self.axes0.set_title(self.name)
117 1 tkerber
            self.axes0.set_ylabel('E [eV]')
118 1 tkerber
            #self.axes0.set_yscale('log')
119 1 tkerber
120 1 tkerber
            self.axes1.set_xlabel('steps')
121 1 tkerber
            self.axes1.set_ylabel('fmax [eV/A]')
122 1 tkerber
            self.axes1.set_yscale('log')
123 1 tkerber
            self.axes1.axhline(self.fmax, color='k', linestyle='--')
124 1 tkerber
            self.fig.savefig(self.name + '.' + format)
125 1 tkerber
126 1 tkerber
class CSVWriter:
127 1 tkerber
    def __init__(self, name):
128 1 tkerber
        self.f = paropen(name + '.csv', 'w')
129 1 tkerber
130 1 tkerber
    def write(self, optimizer, nsteps, E, fc, note=''):
131 1 tkerber
        self.f.write(
132 1 tkerber
            '%s,%i,%i,%f,%s\n' % (optimizer, nsteps, fc, E, note)
133 1 tkerber
        )
134 1 tkerber
135 1 tkerber
    def finalize(self):
136 1 tkerber
        self.f.close()
137 1 tkerber
138 1 tkerber
class DataObserver:
139 1 tkerber
    def __init__(self, atoms):
140 1 tkerber
        self.atoms = atoms
141 1 tkerber
        self.E = []
142 1 tkerber
        self.fmax = []
143 1 tkerber
144 1 tkerber
    def __call__(self):
145 1 tkerber
        self.E.append(self.atoms.get_potential_energy())
146 1 tkerber
        self.fmax.append(np.sqrt((self.atoms.get_forces()**2).sum(axis=1)).max())
147 1 tkerber
148 1 tkerber
    def get_E(self):
149 1 tkerber
        return np.array(self.E)
150 1 tkerber
151 1 tkerber
    def get_fmax(self):
152 1 tkerber
        return np.array(self.fmax)