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
« 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
8class ConstituentStrainCalculator(ClusterExpansionCalculator):
9 """
10 Calculator for handling cluster expansions with strain.
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 """
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)
39 def calculate_total(self, *, occupations: np.ndarray) -> float:
40 """
41 Calculates and returns the total property value of the current
42 configuration.
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
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`.
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
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()