-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #614 from RemDelaporteMathurin/reactions
Reactions
- Loading branch information
Showing
5 changed files
with
332 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import festim as F | ||
from typing import Union | ||
|
||
from ufl import exp | ||
|
||
|
||
class Reaction: | ||
"""A reaction between two species, with a forward and backward rate. | ||
Arguments: | ||
reactant1 (Union[F.Species, F.ImplicitSpecies]): The first reactant. | ||
reactant2 (Union[F.Species, F.ImplicitSpecies]): The second reactant. | ||
product (F.Species): The product. | ||
k_0 (float): The forward rate constant pre-exponential factor. | ||
E_k (float): The forward rate constant activation energy. | ||
p_0 (float): The backward rate constant pre-exponential factor. | ||
E_p (float): The backward rate constant activation energy. | ||
Attributes: | ||
reactant1 (Union[F.Species, F.ImplicitSpecies]): The first reactant. | ||
reactant2 (Union[F.Species, F.ImplicitSpecies]): The second reactant. | ||
product (F.Species): The product. | ||
k_0 (float): The forward rate constant pre-exponential factor. | ||
E_k (float): The forward rate constant activation energy. | ||
p_0 (float): The backward rate constant pre-exponential factor. | ||
E_p (float): The backward rate constant activation energy. | ||
Usage: | ||
>>> # create two species | ||
>>> species1 = F.Species("A") | ||
>>> species2 = F.Species("B") | ||
>>> # create a product species | ||
>>> product = F.Species("C") | ||
>>> # create a reaction between the two species | ||
>>> reaction = Reaction(species1, species2, product, k_0=1.0, E_k=0.2, p_0=0.1, E_p=0.3) | ||
>>> print(reaction) | ||
A + B <--> C | ||
>>> # compute the reaction term at a given temperature | ||
>>> temperature = 300.0 | ||
>>> reaction_term = reaction.reaction_term(temperature) | ||
""" | ||
|
||
def __init__( | ||
self, | ||
reactant1: Union[F.Species, F.ImplicitSpecies], | ||
reactant2: Union[F.Species, F.ImplicitSpecies], | ||
product: F.Species, | ||
k_0: float, | ||
E_k: float, | ||
p_0: float, | ||
E_p: float, | ||
) -> None: | ||
self.reactant1 = reactant1 | ||
self.reactant2 = reactant2 | ||
self.product = product | ||
self.k_0 = k_0 | ||
self.E_k = E_k | ||
self.p_0 = p_0 | ||
self.E_p = E_p | ||
|
||
def __repr__(self) -> str: | ||
return f"Reaction({self.reactant1} + {self.reactant2} <--> {self.product}, {self.k_0}, {self.E_k}, {self.p_0}, {self.E_p})" | ||
|
||
def __str__(self) -> str: | ||
return f"{self.reactant1} + {self.reactant2} <--> {self.product}" | ||
|
||
def reaction_term(self, temperature): | ||
"""Compute the reaction term at a given temperature. | ||
Arguments: | ||
temperature (): The temperature at which the reaction term is computed. | ||
""" | ||
k = self.k_0 * exp(-self.E_k / (F.k_B * temperature)) | ||
p = self.p_0 * exp(-self.E_p / (F.k_B * temperature)) | ||
|
||
c_A = self.reactant1.concentration | ||
c_B = self.reactant2.concentration | ||
|
||
c_C = self.product.solution | ||
return k * c_A * c_B - p * c_C |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import pytest | ||
import festim as F | ||
from dolfinx.fem import FunctionSpace, Function | ||
from dolfinx.mesh import create_unit_cube | ||
from mpi4py import MPI | ||
from ufl import exp | ||
|
||
|
||
def test_reaction_init(): | ||
# create two species | ||
species1 = F.Species("A") | ||
species2 = F.Species("B") | ||
|
||
# create a product species | ||
product = F.Species("C") | ||
|
||
# create a reaction between the two species | ||
reaction = F.Reaction( | ||
species1, species2, product, k_0=1.0, E_k=0.2, p_0=0.1, E_p=0.3 | ||
) | ||
|
||
# check that the attributes are set correctly | ||
assert reaction.reactant1 == species1 | ||
assert reaction.reactant2 == species2 | ||
assert reaction.product == product | ||
assert reaction.k_0 == 1.0 | ||
assert reaction.E_k == 0.2 | ||
assert reaction.p_0 == 0.1 | ||
assert reaction.E_p == 0.3 | ||
|
||
|
||
def test_reaction_repr(): | ||
# create two species | ||
species1 = F.Species("A") | ||
species2 = F.Species("B") | ||
|
||
# create a product species | ||
product = F.Species("C") | ||
|
||
# create a reaction between the two species | ||
reaction = F.Reaction( | ||
species1, species2, product, k_0=1.0, E_k=0.2, p_0=0.1, E_p=0.3 | ||
) | ||
|
||
# check that the __repr__ method returns the expected string | ||
expected_repr = "Reaction(A + B <--> C, 1.0, 0.2, 0.1, 0.3)" | ||
assert repr(reaction) == expected_repr | ||
|
||
|
||
def test_reaction_str(): | ||
# create two species | ||
species1 = F.Species("A") | ||
species2 = F.Species("B") | ||
|
||
# create a product species | ||
product = F.Species("C") | ||
|
||
# create a reaction between the two species | ||
reaction = F.Reaction( | ||
species1, species2, product, k_0=1.0, E_k=0.2, p_0=0.1, E_p=0.3 | ||
) | ||
|
||
# check that the __str__ method returns the expected string | ||
expected_str = "A + B <--> C" | ||
assert str(reaction) == expected_str | ||
|
||
|
||
@pytest.mark.parametrize("temperature", [300.0, 350, 370, 500.0]) | ||
def test_reaction_reaction_term(temperature): | ||
# create two species | ||
species1 = F.Species("A") | ||
species2 = F.Species("B") | ||
|
||
# create a product species | ||
product = F.Species("C") | ||
|
||
# create a reaction between the two species | ||
reaction = F.Reaction( | ||
species1, species2, product, k_0=1.0, E_k=0.2, p_0=0.1, E_p=0.3 | ||
) | ||
|
||
# set the concentrations of the species | ||
mesh = create_unit_cube(MPI.COMM_WORLD, 10, 10, 10) | ||
V = FunctionSpace(mesh, ("Lagrange", 1)) | ||
species1.solution = Function(V) | ||
species2.solution = Function(V) | ||
product.solution = Function(V) | ||
|
||
# test the reaction term at a given temperature | ||
def arrhenius(pre, act, T): | ||
return pre * exp(-act / (F.k_B * T)) | ||
|
||
k = arrhenius(reaction.k_0, reaction.E_k, temperature) | ||
p = arrhenius(reaction.p_0, reaction.E_p, temperature) | ||
expected_reaction_term = ( | ||
k * species1.solution * species2.solution - p * product.solution | ||
) | ||
|
||
assert reaction.reaction_term(temperature) == expected_reaction_term |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters