Coverage for /builds/kinetik161/ase/ase/ga/relax_attaches.py: 22.22%

36 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-12-10 11:04 +0000

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

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

3from math import sqrt 

4 

5import numpy as np 

6 

7 

8class VariansBreak: 

9 

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

11 in order to terminale stalling calculations. 

12 

13 Parameters: 

14 

15 atoms: Atoms object being optimized 

16 dyn: The relaxation object being used 

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

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

19 """ 

20 

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

22 self.atoms = atoms 

23 self.dyn = dyn 

24 self.N = N 

25 self.forces = [] 

26 self.min_stdev = min_stdev 

27 

28 def write(self): 

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

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

31 self.forces.pop(0) 

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

33 self.forces.append(fmax) 

34 

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

36 

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

38 float(len(self.forces))) 

39 

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

41 self.dyn.converged = lambda x: True 

42 

43 

44class DivergenceBreak: 

45 

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

47 in order to terminate diverging calculations. 

48 

49 Parameters: 

50 

51 atoms: Atoms object being optimized 

52 dyn: The relaxation object being used 

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

54 evaluation of the slope 

55 Nmin: The minimal amount of steps required before evaluating 

56 the slope 

57 """ 

58 

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

60 self.atoms = atoms 

61 self.dyn = dyn 

62 self.N = N 

63 self.Nmin = 5 

64 self.energies = [] 

65 

66 def write(self): 

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

68 

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

70 self.energies.pop(0) 

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

72 

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

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

75 y = np.array(self.energies) 

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

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

78 

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

80 self.dyn.converged = lambda x: True