r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1""" An object which can be associated with a local relaxation in order

2to make the relaxations run more smoothly."""

3from math import sqrt

4import numpy as np

7class VariansBreak:

9 """ Helper class which can be attached to a structure optimization,

10 in order to terminale stalling calculations.

12 Parameters:

14 atoms: Atoms object being optimized

15 dyn: The relaxation object being used

16 min_stdev: The limiting std. deviation in forces to terminate at

17 N: The number of steps used to calculate the st. dev.

18 """

20 def __init__(self, atoms, dyn, min_stdev=0.005, N=15):

21 self.atoms = atoms

22 self.dyn = dyn

23 self.N = N

24 self.forces = []

25 self.min_stdev = min_stdev

27 def write(self):

28 """ The method called by the optimizer in each step. """

29 if len(self.forces) >= self.N:

30 self.forces.pop(0)

31 fmax = (self.atoms.get_forces()**2).sum(axis=1).max()**0.5

32 self.forces.append(fmax)

34 m = sum(self.forces) / float(len(self.forces))

36 stdev = sqrt(sum([(c - m)**2 for c in self.forces]) /

37 float(len(self.forces)))

39 if len(self.forces) >= self.N and stdev < self.min_stdev:

40 self.dyn.converged = lambda x: True

43class DivergenceBreak:

45 """ Helper class which can be attached to a structure optimization,

46 in order to terminate diverging calculations.

48 Parameters:

50 atoms: Atoms object being optimized

51 dyn: The relaxation object being used

52 N: The maximum number of recent steps to be included in the

53 evaluation of the slope

54 Nmin: The minimal amount of steps required before evaluating

55 the slope

56 """

58 def __init__(self, atoms, dyn, N=15, Nmin=5):

59 self.atoms = atoms

60 self.dyn = dyn

61 self.N = N

62 self.Nmin = 5

63 self.energies = []

65 def write(self):

66 """ The method called by the optimizer in each step. """

68 if len(self.energies) >= self.N:

69 self.energies.pop(0)

70 self.energies.append(self.atoms.get_potential_energy())

72 if len(self.energies) > self.Nmin:

73 x = np.array(range(len(self.energies)))

74 y = np.array(self.energies)

75 A = np.vstack([x, np.ones(len(x))]).T

76 slope, intersect = np.linalg.lstsq(A, y)[0]

78 if len(self.energies) >= self.N and slope > 0:

79 self.dyn.converged = lambda x: True