Coverage for calorine/tools/structures.py: 100%

27 statements  

« prev     ^ index     » next       coverage.py v7.2.5, created at 2024-10-17 08:55 +0000

1from ase import Atoms 

2from ase.constraints import ExpCellFilter 

3from ase.optimize import BFGS, LBFGS, FIRE, GPMin 

4from ase.optimize.sciopt import SciPyFminBFGS 

5 

6 

7def relax_structure(structure: Atoms, 

8 fmax: float = 0.001, 

9 steps: int = 500, 

10 minimizer: str = 'bfgs', 

11 constant_cell: bool = False, 

12 constant_volume: bool = False, 

13 **kwargs) -> None: 

14 """Relaxes the given structure. 

15 

16 Parameters 

17 ---------- 

18 structure 

19 atomic configuration to relax 

20 fmax 

21 if the absolute force for all atoms falls below this value the relaxation is stopped 

22 steps 

23 maximum number of relaxation steps the minimizer is allowed to take 

24 minimizer 

25 minimizer to use; possible values: 'bfgs', 'lbfgs', 'fire', 'gpmin', 'bfgs-scipy' 

26 constant_cell 

27 if True do not relax the cell or the volume 

28 constant_volume 

29 if True relax the cell shape but keep the volume constant 

30 kwargs 

31 keyword arguments to be handed over to the minimizer; possible arguments can be found 

32 in the `ASE documentation <https://wiki.fysik.dtu.dk/ase/ase/optimize.html>`_ 

33 """ 

34 if structure.calc is None: 

35 raise ValueError('Structure has no attached calculator object') 

36 if constant_cell: 

37 ucf = structure 

38 else: 

39 ucf = ExpCellFilter(structure, constant_volume=constant_volume) 

40 kwargs['logfile'] = kwargs.get('logfile', None) 

41 if minimizer == 'bfgs': 

42 dyn = BFGS(ucf, **kwargs) 

43 dyn.run(fmax=fmax, steps=steps) 

44 elif minimizer == 'lbfgs': 

45 dyn = LBFGS(ucf, **kwargs) 

46 dyn.run(fmax=fmax, steps=steps) 

47 elif minimizer == 'bfgs-scipy': 

48 dyn = SciPyFminBFGS(ucf, **kwargs) 

49 dyn.run(fmax=fmax, steps=steps) 

50 elif minimizer == 'fire': 

51 dyn = FIRE(ucf, **kwargs) 

52 dyn.run(fmax=fmax, steps=steps) 

53 elif minimizer == 'gpmin': 

54 dyn = GPMin(ucf, **kwargs) 

55 dyn.run(fmax=fmax, steps=steps) 

56 else: 

57 raise ValueError(f'Unknown minimizer: {minimizer}')