root / ase / optimize / test / neb.py @ 14
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') |