from typing import Dict
from clease.datastructures import SystemChanges
from clease.montecarlo.observers.mc_observer import MCObserver
__all__ = ("AcceptanceRate",)
[docs]class AcceptanceRate(MCObserver):
"""
Observer that tracks the fraction of monte carlo steps that is accepted
"""
def __init__(self):
super().__init__()
self.num_calls = 0
self.num_accept = 0
@property
def rate(self) -> float:
"""
Acceptance rate
"""
if self.num_calls == 0:
return 0.0
return self.num_accept / self.num_calls
[docs] def reset(self):
"""
Reset the observer
"""
self.num_calls = 0
self.num_accept = 0
def __call__(self, system_changes: SystemChanges) -> None:
"""
Updates the acceptance rate.
:param system_changes: Sequence with introduces changes. A move is considered
accepted if old_symb != new_symb in any of the changes
"""
accepted = any(c.old_symb != c.new_symb for c in system_changes)
if accepted:
self.num_accept += 1
self.num_calls += 1
[docs] def get_averages(self) -> Dict[str, float]:
"""
Return dictionary with the rate such that it is added to thermodynaic quantities
"""
return {"accept_rate": self.rate}