Skip to content

Commit

Permalink
Merge pull request #752 from RemDelaporteMathurin/robin
Browse files Browse the repository at this point in the history
Robin boundary conditions for ParticleFlux
  • Loading branch information
RemDelaporteMathurin authored May 1, 2024
2 parents f57b263 + 1e9c502 commit 0b02ffa
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 2 deletions.
51 changes: 50 additions & 1 deletion festim/boundary_conditions/flux_bc.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ class ParticleFluxBC(FluxBCBase):
is applied
value (float, fem.Constant, callable): the value of the particle flux
species (festim.Species): the species to which the flux is applied
species_dependent_value (dict): a dictionary containing the species that the value. Example: {"name": species}
where "name" is the variable name in the callable value and species is a festim.Species object.
Attributes:
subdomain (festim.SurfaceSubdomain): the surface subdomain where the particle flux
Expand All @@ -151,6 +153,8 @@ class ParticleFluxBC(FluxBCBase):
fenics format
bc_expr (fem.Expression): the expression of the particle flux that is used to
update the value_fenics
species_dependent_value (dict): a dictionary containing the species that the value. Example: {"name": species}
where "name" is the variable name in the callable value and species is a festim.Species object.
Usage:
Expand All @@ -160,11 +164,56 @@ class ParticleFluxBC(FluxBCBase):
>>> ParticleFluxBC(subdomain=my_subdomain, value=lambda t: 1 + t, species="H")
>>> ParticleFluxBC(subdomain=my_subdomain, value=lambda T: 1 + T, species="H")
>>> ParticleFluxBC(subdomain=my_subdomain, value=lambda x, t: 1 + x[0] + t, species="H")
>>> ParticleFluxBC(subdomain=my_subdomain, value=lambda c1: 2 * c1**2, species="H", species_dependent_value={"c1": species1})
"""

def __init__(self, subdomain, value, species):
def __init__(self, subdomain, value, species, species_dependent_value={}):
super().__init__(subdomain=subdomain, value=value)
self.species = species
self.species_dependent_value = species_dependent_value

def create_value_fenics(self, mesh, temperature, t: fem.Constant):
"""Creates the value of the boundary condition as a fenics object and sets it to
self.value_fenics.
If the value is a constant, it is converted to a fenics.Constant.
If the value is a function of t, it is converted to a fenics.Constant.
Otherwise, it is converted to a ufl Expression
Args:
mesh (dolfinx.mesh.Mesh) : the mesh
temperature (float): the temperature
t (dolfinx.fem.Constant): the time
"""
x = ufl.SpatialCoordinate(mesh)

if isinstance(self.value, (int, float)):
self.value_fenics = F.as_fenics_constant(mesh=mesh, value=self.value)

elif callable(self.value):
arguments = self.value.__code__.co_varnames

if "t" in arguments and "x" not in arguments and "T" not in arguments:
# only t is an argument
if not isinstance(self.value(t=float(t)), (float, int)):
raise ValueError(
f"self.value should return a float or an int, not {type(self.value(t=float(t)))} "
)
self.value_fenics = F.as_fenics_constant(
mesh=mesh, value=self.value(t=float(t))
)
else:
kwargs = {}
if "t" in arguments:
kwargs["t"] = t
if "x" in arguments:
kwargs["x"] = x
if "T" in arguments:
kwargs["T"] = temperature

for name, species in self.species_dependent_value.items():
kwargs[name] = species.concentration

self.value_fenics = self.value(**kwargs)


class HeatFluxBC(FluxBCBase):
Expand Down
25 changes: 24 additions & 1 deletion test/test_flux_bc.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,29 @@ def test_create_value_fenics_value(value, expected_value):
assert np.isclose(bc.value_fenics.value, expected_value)


def test_create_value_fenics_dependent_conc():
"""Test that the value_fenics of ParticleFluxBC is set correctly when the value is dependent on the concentration"""
# BUILD
left = F.SurfaceSubdomain1D(1, x=0)
my_species = F.Species("test")
my_species.solution = F.as_fenics_constant(12, mesh)
T = F.as_fenics_constant(1, mesh)
t = F.as_fenics_constant(0, mesh)
bc = F.ParticleFluxBC(
subdomain=left,
value=lambda c: 1.0 + c,
species=my_species,
species_dependent_value={"c": my_species},
)

# RUN
bc.create_value_fenics(mesh, T, t)

# TEST
assert isinstance(bc.value_fenics, ufl.core.expr.Expr)
assert bc.value_fenics == 1.0 + my_species.solution


def test_value_fenics_setter_error():
left = F.SurfaceSubdomain1D(1, x=0)
my_species = F.Species("test")
Expand Down Expand Up @@ -237,7 +260,7 @@ def test_create_value_fenics_type_HeatFluxBC(value, expected_type):
(lambda t: 50.0 if t < 1 else 0.0, 50),
],
)
def test_create_value_fenics_value(value, expected_value):
def test_create_value_fenics_value_HeatFluxBC(value, expected_value):
"""Test that"""
# BUILD
left = F.SurfaceSubdomain1D(1, x=0)
Expand Down

0 comments on commit 0b02ffa

Please sign in to comment.