root / ase / optimize / test / neb.py @ 1
Historique | Voir | Annoter | Télécharger (2,12 ko)
1 | 1 | tkerber | #/usr/bin/env python
|
---|---|---|---|
2 | 1 | tkerber | #PBS -l nodes=4:ppn=8
|
3 | 1 | tkerber | #PBS -l walltime=13:00:00
|
4 | 1 | tkerber | from ase.optimize import QuasiNewton |
5 | 1 | tkerber | from ase.constraints import FixAtoms |
6 | 1 | tkerber | from ase.calculators.emt import EMT |
7 | 1 | tkerber | from ase.neb import NEB |
8 | 1 | tkerber | from ase.lattice.surface import fcc100, add_adsorbate |
9 | 1 | tkerber | from ase.optimize.test import run_test |
10 | 1 | tkerber | from gpaw import GPAW, Mixer, PoissonSolver |
11 | 1 | tkerber | import gpaw.mpi as mpi |
12 | 1 | tkerber | |
13 | 1 | tkerber | |
14 | 1 | tkerber | name = 'neb'
|
15 | 1 | tkerber | |
16 | 1 | tkerber | def get_atoms(): |
17 | 1 | tkerber | # 2x2-Al(001) surface with 3 layers and an
|
18 | 1 | tkerber | # Au atom adsorbed in a hollow site:
|
19 | 1 | tkerber | slab = fcc100('Al', size=(2, 2, 3)) |
20 | 1 | tkerber | add_adsorbate(slab, 'Au', 1.7, 'hollow') |
21 | 1 | tkerber | slab.center(axis=2, vacuum=4.0) |
22 | 1 | tkerber | |
23 | 1 | tkerber | # Fix second and third layers:
|
24 | 1 | tkerber | mask = [atom.tag > 1 for atom in slab] |
25 | 1 | tkerber | slab.set_constraint(FixAtoms(mask=mask)) |
26 | 1 | tkerber | |
27 | 1 | tkerber | # Use EMT potential:
|
28 | 1 | tkerber | slab.set_calculator(EMT()) |
29 | 1 | tkerber | |
30 | 1 | tkerber | # Initial state:
|
31 | 1 | tkerber | qn = QuasiNewton(slab, logfile=None)
|
32 | 1 | tkerber | qn.run(fmax=0.05)
|
33 | 1 | tkerber | initial = slab.copy() |
34 | 1 | tkerber | |
35 | 1 | tkerber | # Final state:
|
36 | 1 | tkerber | slab[-1].x += slab.get_cell()[0, 0] / 2 |
37 | 1 | tkerber | qn = QuasiNewton(slab, logfile=None)
|
38 | 1 | tkerber | qn.run(fmax=0.05)
|
39 | 1 | tkerber | final = slab.copy() |
40 | 1 | tkerber | |
41 | 1 | tkerber | # Setup a NEB calculation
|
42 | 1 | tkerber | constraint = FixAtoms(mask=[atom.tag > 1 for atom in initial]) |
43 | 1 | tkerber | |
44 | 1 | tkerber | images = [initial] |
45 | 1 | tkerber | for i in range(3): |
46 | 1 | tkerber | image = initial.copy() |
47 | 1 | tkerber | image.set_constraint(constraint) |
48 | 1 | tkerber | images.append(image) |
49 | 1 | tkerber | |
50 | 1 | tkerber | images.append(final) |
51 | 1 | tkerber | |
52 | 1 | tkerber | neb = NEB(images, parallel=mpi.parallel) |
53 | 1 | tkerber | neb.interpolate() |
54 | 1 | tkerber | |
55 | 1 | tkerber | def set_calculator(calc): |
56 | 1 | tkerber | i = 0
|
57 | 1 | tkerber | for image in neb.images[1:-1]: |
58 | 1 | tkerber | if not mpi.parallel or mpi.rank // (mpi.size // 3) == i: |
59 | 1 | tkerber | image.set_calculator(calc) |
60 | 1 | tkerber | i += 1
|
61 | 1 | tkerber | neb.set_calculator = set_calculator |
62 | 1 | tkerber | |
63 | 1 | tkerber | return neb
|
64 | 1 | tkerber | |
65 | 1 | tkerber | def get_calculator_emt(): |
66 | 1 | tkerber | return EMT()
|
67 | 1 | tkerber | |
68 | 1 | tkerber | def get_calculator_gpaw(): |
69 | 1 | tkerber | if mpi.parallel:
|
70 | 1 | tkerber | assert mpi.size % 3 == 0 |
71 | 1 | tkerber | s = mpi.size // 3
|
72 | 1 | tkerber | r0 = mpi.rank // s * s |
73 | 1 | tkerber | comm = range(r0, r0 + s)
|
74 | 1 | tkerber | else:
|
75 | 1 | tkerber | comm = mpi.world |
76 | 1 | tkerber | calc = GPAW(h=0.25,
|
77 | 1 | tkerber | kpts=(2, 2, 1), |
78 | 1 | tkerber | communicator=comm, |
79 | 1 | tkerber | txt='neb-%d.txt' % r0)
|
80 | 1 | tkerber | return calc
|
81 | 1 | tkerber | |
82 | 1 | tkerber | run_test(get_atoms, get_calculator_emt, name + '-emt')
|
83 | 1 | tkerber | run_test(get_atoms, get_calculator_gpaw, name + '-gpaw') |