Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored defect Boltzmann factor code #17

Merged
merged 1 commit into from
Jul 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 4 additions & 38 deletions pyscses/defect_at_site.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ def potential_energy(self,
"""
return (phi * self.valence) + self.energy

def boltzmann_one(self,
phi: float,
temp: float) -> float:
r"""Boltzmann statistics calculation - part one
def boltzmann_factor(self,
phi: float,
temp: float) -> float:
r"""Boltzmann factor for this defect species.

.. math:: \exp\left(\frac{-\Phi z+\Delta E}{k_BT}\right)

Expand All @@ -70,37 +70,3 @@ def boltzmann_one(self,

"""
return math.exp(-self.potential_energy(phi) / (boltzmann_eV * temp))

def boltzmann_two(self,
phi: float,
temp: float) -> float:
r"""Boltzmann statistics calculation - part two

.. math:: x\exp\left(\frac{-\Phi z+\Delta E}{K_BT}\right)

Args:
phi (float): Electrostatic potential.
temp (float): Temperature of calculation.

Returns:
float: Boltzmann statistics * mole fraction

"""
return self.mole_fraction * self.boltzmann_one(phi, temp)

def boltzmann_three(self,
phi: float,
temp: float) -> float:
r"""Boltzmann statistics calculation - part three

.. math:: x\left(\exp\left(-\frac{\Phi z+\Delta E}{K_BT}\right)-1\right)

Args:
phi (float): Electrostatic potential.
temp (float): Temperature of calculation.

Returns:
float: ( Boltzmann statistics - 1 ) * mole fraction.

"""
return self.mole_fraction * (self.boltzmann_one(phi, temp) - 1.0)
71 changes: 7 additions & 64 deletions pyscses/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def __init__(self,
scaling (optional, list(float): Optional list of scaling factors for the net charge at this site. Default scaling for each defect species is 1.0.
valence (optional, float): Optional formal valence for this site in the absence of any defects. Default is 0.0.

Raise:
Raises:
ValueError if the number of DefectSpecies != the number of defect segregation energies != the number of scaling factors (if passed).

"""
Expand Down Expand Up @@ -111,33 +111,14 @@ def average_local_energy(self,
else:
raise ValueError("TODO")

def sum_of_boltzmann_three(self,
phi: float,
temp : float) -> float:
"""
Calculates the sum of the calculated "boltzmann_three" values for each defect at each site.

.. math:: \sum_i(x_i\exp(-\Phi_xz/kT) - 1)

Args:
phi (float): Electrostatic potential at the site.
temp (float): Temperature in Kelvin.

Returns:
float: The sum of Boltzmann terms.

"""
return sum([d.boltzmann_three(phi, temp) for d in self.defects])

def probabilities(self,
phi: float,
temp: float) -> List[float]:
"""Calculates the probabilities of this site being occupied by each defect species.
Derived from the chemical potential term for a Fermi-Dirac like distribution.

Args:
phi (float): Electrostatic potential at this site.
temp (float): Temperature in Kelvin.
phi (float): Electrostatic potential at this site in Volts.
temp (float): Temperature in Kelvin.

Returns:
list: Probabilities of site occupation on a 1D grid.
Expand All @@ -148,23 +129,23 @@ def probabilities(self,
if defect.fixed:
probabilities.append(defect.mole_fraction)
else:
probabilities.append(defect.boltzmann_two(phi, temp) /
(1.0 + self.sum_of_boltzmann_three(phi, temp)))
probabilities.append(defect.mole_fraction * defect.boltzmann_factor(phi, temp) /
(1.0 + sum([d.mole_fraction * (d.boltzmann_factor(phi, temp) - 1.0)
for d in self.defects])))
return probabilities

def defect_valences(self) -> np.ndarray:
"""Returns an array of valences for each defect from self.defects """
return np.array([d.valence for d in self.defects])


def charge(self,
phi: float,
temp: float) -> float:
"""
Charge at this site (in Coulombs).

Args:
phi (float): Electrostatic potential at this site (units?).
phi (float): Electrostatic potential at this site in Volts.
temp (float): Temperature in Kelvin.

Returns:
Expand All @@ -175,41 +156,3 @@ def charge(self,
* self.defect_valences()
* self.scaling)) * fundamental_charge
return charge

def probabilities_boltz(self,
phi: float,
temp: float) -> List[float]:
"""

Calculates the probability of this site being occupied by each defect.

Args:
phi (float): Electrostatic potential at this site.
temp (float): Temperature in Kelvin.

Returns:
list: Probabilities of site occupation on a 1D grid.

"""
boltzmann_probabilities = [defect.boltzmann_two(phi, temp) for defect in self.defects]
return boltzmann_probabilities

# BEN: Does not appear to be used?
# def charge_boltz(self,
# phi: float,
# temp: float) -> float:
# """
# Calculates the charge in Coulombs at this site using Boltzmann probabilities.
#
# Args:
# phi (float): Electrostatic potential at this site
# temp (float): Temperature in Kelvin.
#
# Returns:
# np.array: The charge on a 1D grid.
# """
# charge = np.sum(self.probabilities_boltz(phi, temp)
# * self.defect_valences()
# * self.scaling) * fundamental_charge
# return charge

32 changes: 6 additions & 26 deletions tests/test_defect_at_site.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from unittest.mock import patch, Mock

class TestDefectAtSiteInit(unittest.TestCase):

def test_init(self):
mock_site = Mock(spec=Site)
defect_at_site = DefectAtSite(label='A',
Expand All @@ -19,7 +19,7 @@ def test_init(self):
self.assertEqual(defect_at_site.mobility, 2.3)
self.assertEqual(defect_at_site.site, mock_site),
self.assertEqual(defect_at_site.fixed, False)

def test_init_with_fixed_equals_true(self):
mock_site = Mock(spec=Site)
defect_at_site = DefectAtSite(label='A',
Expand All @@ -30,7 +30,7 @@ def test_init_with_fixed_equals_true(self):
site=mock_site,
fixed=True)
self.assertEqual(defect_at_site.fixed, True)

class TestDefectAtSite(unittest.TestCase):

def setUp(self):
Expand All @@ -43,36 +43,16 @@ def setUp(self):

def test_potential_energy(self):
phi = 0.5
self.assertEqual(self.defect.potential_energy(phi), 2.0)
self.assertEqual(self.defect.potential_energy(phi), 2.0)

def test_boltzmann_one(self):
def test_boltzmann_factor(self):
phi = 0.5
temp = 298.0
with patch('pyscses.defect_at_site.DefectAtSite.potential_energy') as mock_potential_energy:
mock_potential_energy.return_value = 2.0
self.assertAlmostEqual(self.defect.boltzmann_one(phi=phi, temp=temp),
self.assertAlmostEqual(self.defect.boltzmann_factor(phi=phi, temp=temp),
1.4996341881113563e-34, places=40)
mock_potential_energy.assert_called_with(phi)

def test_boltzmann_two(self):
phi = 0.5
temp = 298.0
self.defect.mole_fraction = 1.5
with patch('pyscses.defect_at_site.DefectAtSite.boltzmann_one') as mock_boltzmann_one:
mock_boltzmann_one.return_value = 2.0
self.assertEqual(self.defect.boltzmann_two(phi, temp), 3.0)
mock_boltzmann_one.assert_called_with(phi, temp)

def test_boltzmann_three(self):
phi = 0.5
temp = 298.0
self.defect.mole_fraction = 1.5
with patch('pyscses.defect_at_site.DefectAtSite.boltzmann_one') as mock_boltzmann_one:
mock_boltzmann_one.return_value = 2.0
self.assertEqual(self.defect.boltzmann_three(phi, temp), 1.5)
mock_boltzmann_one.assert_called_with(phi, temp)



if __name__ == '__main__':
unittest.main()