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) |