Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from ase.optimize.optimize import Optimizer 

2from ase.units import Ha, Bohr 

3 

4 

5class Berny(Optimizer): 

6 def __init__(self, atoms, restart=None, logfile='-', trajectory=None, 

7 master=None, dihedral=True): 

8 """Berny optimizer. 

9 

10 This is a light ASE wrapper around the ``Berny`` optimizer from 

11 Pyberny_. It is based on a redundant set of internal coordinates, and as 

12 such is best suited for optimizing covalently bonded molecules. It does 

13 not support periodic boundary conditions. You can find more information 

14 on the Pyberny_ website. 

15 

16 This optimizer is experimental, and while it can be quite efficient when 

17 it works, it can sometimes fail entirely. These issues are most likely 

18 related to almost linear bonding angles. For context, see the 

19 discussions `here <https://github.com/jhrmnn/pyberny/issues/23>`__ and 

20 `here <https://gitlab.com/ase/ase/-/merge_requests/889>`__. 

21 

22 .. _Pyberny: https://github.com/jhrmnn/pyberny 

23 

24 Parameters: 

25 

26 atoms: Atoms object 

27 The Atoms object to relax. 

28 

29 restart: string 

30 Pickle file used to store internal state. If set, file with 

31 such a name will be searched and internal state stored will 

32 be used, if the file exists. 

33 

34 trajectory: string 

35 Pickle file used to store trajectory of atomic movement. 

36 

37 logfile: file object or str 

38 If *logfile* is a string, a file with that name will be opened. 

39 Use '-' for stdout. 

40 

41 master: boolean 

42 Defaults to None, which causes only rank 0 to save files. If 

43 set to true, this rank will save files. 

44 

45 dihedral: boolean 

46 Defaults to True, which means that dihedral angles will be used. 

47 """ 

48 from berny import Berny as _Berny, Geometry 

49 

50 self._restart_data = None # Optimizer.__init__() may overwrite 

51 Optimizer.__init__(self, atoms, restart, logfile, trajectory, master) 

52 geom = Geometry(atoms.get_chemical_symbols(), atoms.positions) 

53 self._berny = _Berny( 

54 geom, 

55 debug=True, 

56 restart=self._restart_data, 

57 maxsteps=10000000000, # TODO copied from ase.optimize.Optimizer 

58 gradientmax=0., 

59 gradientrms=0., 

60 stepmax=0., 

61 steprms=0., 

62 dihedral=dihedral, 

63 ) 

64 

65 # Berny yields the initial geometry the first time because it is 

66 # typically used as a generator, see berny.optimize() 

67 next(self._berny) 

68 

69 def step(self, forces=None): 

70 if forces is None: 

71 forces = self.atoms.get_forces() 

72 energy = self.atoms.get_potential_energy() 

73 gradients = -forces 

74 debug = self._berny.send((energy / Ha, gradients / Ha * Bohr)) 

75 self.dump(debug) 

76 geom = next(self._berny) 

77 self.atoms.positions[:] = geom.coords 

78 

79 def read(self): 

80 self._restart_data = self.load()