Coverage for mchammer/calculators/constituent_strain_calculator.py: 100%

21 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2024-12-26 04:12 +0000

1from icet.tools import ConstituentStrain 

2from icet import ClusterExpansion 

3from mchammer.calculators import ClusterExpansionCalculator 

4from typing import List, Union 

5import numpy as np 

6 

7 

8class ConstituentStrainCalculator(ClusterExpansionCalculator): 

9 """ 

10 Calculator for handling cluster expansions with strain. 

11 

12 Parameters 

13 ---------- 

14 constituent_strain 

15 :class:`ConstituentStrain` object defining the strain energy 

16 properties of the system. The supercell used to 

17 create this object should correspond to the one 

18 used when running Monte Carlo simulations with this 

19 calculator 

20 cluster_expansion 

21 Cluster expansion based on which to set up :class:`ClusterExpansionCalculator`. 

22 name 

23 Human-readable identifier for this calculator. 

24 scaling 

25 Scaling factor applied to the property value predicted by the 

26 cluster expansion. 

27 """ 

28 

29 def __init__(self, constituent_strain: ConstituentStrain, 

30 cluster_expansion: ClusterExpansion, 

31 name: str = 'Constituent Strain Calculator', 

32 scaling: Union[float, int] = None): 

33 self.constituent_strain = constituent_strain 

34 super().__init__(structure=constituent_strain.supercell, 

35 cluster_expansion=cluster_expansion, 

36 name=name, 

37 scaling=scaling) 

38 

39 def calculate_total(self, *, occupations: np.ndarray) -> float: 

40 """ 

41 Calculates and returns the total property value of the current 

42 configuration. 

43 

44 Parameters 

45 ---------- 

46 occupations 

47 The entire occupation vector (i.e., an array of atomic numbers as integers). 

48 """ 

49 e = super().calculate_total(occupations=occupations) 

50 e += len(occupations) * \ 

51 self.constituent_strain.get_constituent_strain(occupations) 

52 return e 

53 

54 def calculate_change(self, *, sites: List[int], 

55 current_occupations: List[int], 

56 new_site_occupations: List[int]) -> float: 

57 """ 

58 Calculates and returns the sum of the contributions to the property 

59 due to the sites specified in :attr:`sites`. 

60 

61 Parameters 

62 ---------- 

63 sites 

64 Indices of sites at which occupations will be changed. 

65 current_occupations 

66 Entire occupation vector (atomic numbers) before change. 

67 new_site_occupations 

68 Atomic numbers after change at the sites defined by :attr:`sites`. 

69 """ 

70 if len(new_site_occupations) > 1: 

71 raise NotImplementedError('Only single flips are currently allowed in ' 

72 'conjunction with the constituent strain calculator.') 

73 e = super().calculate_change(sites=sites, 

74 current_occupations=current_occupations, 

75 new_site_occupations=new_site_occupations) 

76 de_cs = self.constituent_strain.get_constituent_strain_change(current_occupations, 

77 sites[0]) 

78 e += len(current_occupations) * de_cs 

79 return e 

80 

81 def accept_change(self): 

82 """Informs the :class:`ConstituentStrain` object that the most recent 

83 change was accepted, such that the new structure factor can be 

84 stored. 

85 """ 

86 self.constituent_strain.accept_change()