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

Support extra product species in degradation mechanisms #29

Merged
merged 13 commits into from
Jan 30, 2024
Merged
1 change: 1 addition & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ disable=raw-checker-failed,
too-many-arguments,
too-many-locals,
too-many-statements,
too-many-lines,
protected-access

# Enable the message, report, category or checker with the given id(s). You can
Expand Down
90 changes: 45 additions & 45 deletions src/rfbzero/degradation.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
class DegradationMechanism(ABC):
"""Abstract base class to be implemented by specific degradation mechanisms."""

def __init__(self, **c_products: float):
self.c_products = c_products

@abstractmethod
def degrade(self, c_ox: float, c_red: float, time_step: float) -> tuple[float, float]:
"""Applies desired degradation mechanisms to oxidized/reduced species at each time step."""
Expand All @@ -28,6 +31,7 @@ class ChemicalDegradationOxidized(DegradationMechanism):
"""

def __init__(self, rate_order: int, rate_constant: float) -> None:
super().__init__()
self.rate_order = rate_order
self.rate_constant = rate_constant

Expand All @@ -53,15 +57,15 @@ def degrade(self, c_ox: float, c_red: float, time_step: float) -> tuple[float, f

Returns
-------
c_ox : float
Updated concentration of oxidized species (M).
c_red : float
Unchanged concentration of reduced species (M).
delta_ox : float
Change in concentration of oxidized species (M).
delta_red : float
Change in concentration of reduced species (M). This will always be zero.

"""

c_ox -= (time_step * self.rate_constant * (c_ox ** self.rate_order))
return c_ox, c_red
delta_ox = -(time_step * self.rate_constant * (c_ox ** self.rate_order))
return delta_ox, 0.0


class ChemicalDegradationReduced(DegradationMechanism):
Expand All @@ -78,6 +82,7 @@ class ChemicalDegradationReduced(DegradationMechanism):
"""

def __init__(self, rate_order: int, rate_constant: float) -> None:
super().__init__()
self.rate_order = rate_order
self.rate_constant = rate_constant

Expand All @@ -103,15 +108,15 @@ def degrade(self, c_ox: float, c_red: float, time_step: float) -> tuple[float, f

Returns
-------
c_ox : float
Unchanged concentration of oxidized species (M).
c_red : float
Updated concentration of reduced species (M).
delta_ox : float
Change in concentration of oxidized species (M). This will always be zero.
delta_red : float
Change in concentration of reduced species (M).

"""

c_red -= (time_step * self.rate_constant * (c_red ** self.rate_order))
return c_ox, c_red
delta_red = -(time_step * self.rate_constant * (c_red ** self.rate_order))
return 0.0, delta_red


class AutoOxidation(DegradationMechanism):
Expand All @@ -134,6 +139,7 @@ class AutoOxidation(DegradationMechanism):
"""

def __init__(self, rate_constant: float, c_oxidant: float = 0.0, oxidant_stoich: int = 0) -> None:
super().__init__()
self.rate_constant = rate_constant
self.c_oxidant = c_oxidant
self.oxidant_stoich = oxidant_stoich
Expand Down Expand Up @@ -166,20 +172,18 @@ def degrade(self, c_ox: float, c_red: float, time_step: float) -> tuple[float, f

Returns
-------
c_ox : float
Updated concentration of oxidized species (M).
c_red : float
Updated concentration of reduced species (M).
delta_ox : float
Change in concentration of oxidized species (M).
delta_red : float
Change in concentration of reduced species (M).

"""

delta_concentration = time_step * self.rate_constant * c_red * (self.c_oxidant ** self.oxidant_stoich)

c_ox += delta_concentration
c_red -= delta_concentration
self.c_oxidant -= delta_concentration * self.oxidant_stoich
self.c_oxidant = max(self.c_oxidant, 0.0)
return c_ox, c_red
return delta_concentration, -delta_concentration


class AutoReduction(DegradationMechanism):
Expand All @@ -201,6 +205,7 @@ class AutoReduction(DegradationMechanism):

"""
def __init__(self, rate_constant: float, c_reductant: float = 0.0, reductant_stoich: int = 0) -> None:
super().__init__()
self.rate_constant = rate_constant
self.c_reductant = c_reductant
self.reductant_stoich = reductant_stoich
Expand Down Expand Up @@ -233,20 +238,18 @@ def degrade(self, c_ox: float, c_red: float, time_step: float) -> tuple[float, f

Returns
-------
c_ox : float
Updated concentration of oxidized species (M).
c_red : float
Updated concentration of reduced species (M).
delta_ox : float
Change in concentration of oxidized species (M).
delta_red : float
Change in concentration of reduced species (M).

"""

delta_concentration = time_step * self.rate_constant * c_ox * (self.c_reductant ** self.reductant_stoich)

c_ox -= delta_concentration
c_red += delta_concentration
self.c_reductant -= delta_concentration * self.reductant_stoich
self.c_reductant = max(self.c_reductant, 0.0)
return c_ox, c_red
return -delta_concentration, delta_concentration


class Dimerization(DegradationMechanism):
Expand All @@ -265,17 +268,17 @@ class Dimerization(DegradationMechanism):
"""

def __init__(self, forward_rate_constant: float, backward_rate_constant: float, c_dimer: float = 0.0) -> None:
super().__init__(c_dimer=c_dimer)
self.forward_rate_constant = forward_rate_constant
self.backward_rate_constant = backward_rate_constant
self.c_dimer = c_dimer

if self.forward_rate_constant <= 0.0:
raise ValueError("'forward_rate_constant' must be > 0.0")

if self.backward_rate_constant <= 0.0:
raise ValueError("'backward_rate_constant' must be > 0.0")

if self.c_dimer < 0.0:
if c_dimer < 0.0:
raise ValueError("'c_dimer' must be >= 0.0")

def degrade(self, c_ox: float, c_red: float, time_step: float) -> tuple[float, float]:
Expand All @@ -294,22 +297,19 @@ def degrade(self, c_ox: float, c_red: float, time_step: float) -> tuple[float, f

Returns
-------
c_ox : float
Concentration of oxidized species (M).
c_red : float
Concentration of reduced species (M).
delta_ox : float
Change in concentration of oxidized species (M).
delta_red : float
Change in concentration of reduced species (M).

"""

delta_concentration = time_step * (
(self.forward_rate_constant * c_ox * c_red) - (self.backward_rate_constant * self.c_dimer)
(self.forward_rate_constant * c_ox * c_red) - (self.backward_rate_constant * self.c_products['c_dimer'])
jeremyfell marked this conversation as resolved.
Show resolved Hide resolved
)

self.c_dimer += delta_concentration
c_red -= delta_concentration
c_ox -= delta_concentration

return c_ox, c_red
self.c_products['c_dimer'] += delta_concentration
return -delta_concentration, -delta_concentration


class MultiDegradationMechanism(DegradationMechanism):
Expand All @@ -325,6 +325,7 @@ class MultiDegradationMechanism(DegradationMechanism):

"""
def __init__(self, mechanisms: list[DegradationMechanism]) -> None:
super().__init__()
self.mechanisms = mechanisms

for mechanism in self.mechanisms:
Expand All @@ -347,13 +348,12 @@ def degrade(self, c_ox: float, c_red: float, time_step: float) -> tuple[float, f

Returns
-------
c_ox : float
Concentration of oxidized species (M).
c_red : float
Concentration of reduced species (M).
delta_ox : float
Change in concentration of oxidized species (M).
delta_red : float
Change in concentration of reduced species (M).

"""

for mechanism in self.mechanisms:
c_ox, c_red = mechanism.degrade(c_ox, c_red, time_step)
return c_ox, c_red
deltas = [mechanism.degrade(c_ox, c_red, time_step) for mechanism in self.mechanisms]
return sum(delta_ox for delta_ox, _ in deltas), sum(delta_red for _, delta_red in deltas)
jeremyfell marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading