Skip to content
Draft
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
1 change: 1 addition & 0 deletions src/festim/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
)
from .hydrogen_transport_problem import (
HydrogenTransportProblem,
HydrogenTransportProblemDG,
HydrogenTransportProblemDiscontinuous,
HydrogenTransportProblemDiscontinuousChangeVar,
)
Expand Down
10 changes: 9 additions & 1 deletion src/festim/boundary_conditions/__init__.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
from .dirichlet_bc import DirichletBCBase, FixedConcentrationBC, FixedTemperatureBC
from .dirichlet_bc import (
DirichletBCBase,
FixedConcentrationBC,
FixedConcentrationInflowBC,
FixedTemperatureBC,
)
from .flux_bc import FluxBCBase, HeatFluxBC, ParticleFluxBC
from .henrys_bc import HenrysBC
from .outflow_bc import OutflowBC
from .sieverts_bc import SievertsBC
from .surface_reaction import SurfaceReactionBC, SurfaceReactionBCpartial

__all__ = [
"DirichletBCBase",
"FixedConcentrationBC",
"FixedConcentrationInflowBC",
"FixedTemperatureBC",
"FluxBCBase",
"HeatFluxBC",
"HenrysBC",
"OutflowBC",
"ParticleFluxBC",
"SievertsBC",
"SurfaceReactionBC",
Expand Down
51 changes: 51 additions & 0 deletions src/festim/boundary_conditions/dirichlet_bc.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from festim import helpers
from festim import subdomain as _subdomain
from festim.advection import VelocityField
from festim.species import Species


Expand Down Expand Up @@ -421,3 +422,53 @@ def create_value(self, function_space: fem.FunctionSpace, t: fem.Constant):
helpers.get_interpolation_points(function_space.element),
)
self.value_fenics.interpolate(self.bc_expr)


class FixedConcentrationInflowBC(FixedConcentrationBC):
"""Inflow boundary condition with fixed concentration.

This is a specific case of `FixedConcentrationBC` where the value of the
boundary condition is fixed and does not depend on time or space. It is
used for inflow boundary conditions where the concentration of the species
entering the domain is known and constant.

Args:
subdomain (festim.Subdomain): the surface subdomain where the boundary
condition is applied
value: The value of the boundary condition. It can be a function of
space and/or time
species: The name of the species

"""

def __init__(
self,
subdomain: _subdomain.SurfaceSubdomain,
value: np.ndarray | fem.Constant | int | float | Callable,
species: Species,
velocity_field: fem.Function,
):
super().__init__(subdomain, value, species, enforce_weakly=False)

self.velocity_field = velocity_field

@property
def velocity_field(self):
return self._velocity_field

@velocity_field.setter
def velocity_field(self, value):
err_message = f"velocity must be a fem.Function, or callable not {type(value)}"
if value is None:
self._velocity = VelocityField(value)
elif isinstance(
value,
fem.Function,
):
self._velocity = VelocityField(value)
elif isinstance(value, fem.Constant | fem.Expression | ufl.core.expr.Expr):
raise TypeError(err_message)
elif callable(value):
self._velocity = VelocityField(value)
else:
raise TypeError(err_message)
110 changes: 110 additions & 0 deletions src/festim/boundary_conditions/outflow_bc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import ufl
from dolfinx import fem

from festim import subdomain as _subdomain
from festim.advection import VelocityField
from festim.species import Species


class OutflowBC:
"""
Outflow boundary condition class

dot(velocity, n) * u * v * ds

This term allows the species to flow across the boundary due to advection. It arises
from integrating the conservative form of the advection term by parts in the weak
formulation.

Args:
velocity: The velocity field at the outflow boundary condition
species: The species for which the outflow boundary condition is applied, can be
a list of species or a single species
subdomain: The surface subdomain where the boundary condition is applied

Attributes:
velocity: The velocity field at the outflow boundary condition
species: The species for which the outflow boundary condition is applied, can be
a list of species or a single species
subdomain: The surface subdomain where the boundary condition is applied

"""

velocity: VelocityField
species: list[Species]
subdomain: _subdomain.SurfaceSubdomain

def __init__(
self,
velocity: fem.Function,
species: Species | list[Species],
subdomain: _subdomain.SurfaceSubdomain,
):
self.subdomain = subdomain
self.velocity = velocity
self.species = species

@property
def velocity(self):
return self._velocity

@velocity.setter
def velocity(self, value):
err_message = f"velocity must be a fem.Function, or callable not {type(value)}"
if value is None:
self._velocity = VelocityField(value)
elif isinstance(
value,
fem.Function,
):
self._velocity = VelocityField(value)
elif isinstance(value, fem.Constant | fem.Expression | ufl.core.expr.Expr):
raise TypeError(err_message)
elif callable(value):
self._velocity = VelocityField(value)
else:
raise TypeError(err_message)

@property
def species(self) -> list[Species]:
return self._species

@species.setter
def species(self, value):
if not isinstance(value, list):
value = [value]
# check that all species are of type festim.Species
for spe in value:
if not isinstance(spe, Species):
raise TypeError(
f"elements of species must be of type festim.Species not "
f"{type(spe)}"
)
self._species = value

@property
def subdomain(self):
return self._subdomain

@subdomain.setter
def subdomain(self, value):
if value is None:
self._subdomain = value
elif isinstance(value, _subdomain.SurfaceSubdomain):
self._subdomain = value
else:
raise TypeError(
f"Subdomain must be a festim.SurfaceSubdomain object, not {type(value)}"
)

@property
def time_dependent(self):
if self.velocity is None:
raise TypeError("Value must be given to determine if its time dependent")
if isinstance(self.velocity, fem.Constant):
return False
if callable(self.velocity):
arguments = self.velocity.__code__.co_varnames
return "t" in arguments
else:
return False
Loading
Loading