Skip to content

Commit

Permalink
Merge pull request #15 from RemDelaporteMathurin/refactoring_bc_multi…
Browse files Browse the repository at this point in the history
…species

Refactoring bc multispecies
  • Loading branch information
jhdark authored Oct 25, 2023
2 parents 39d5001 + f4d017f commit 6de35aa
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 53 deletions.
15 changes: 1 addition & 14 deletions festim/boundary_conditions/dirichlet_bc.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def create_value(
if "t" in arguments and "x" not in arguments and "T" not in arguments:
# only t is an argument
self.value_fenics = F.as_fenics_constant(
mesh=mesh, value=self.value(t=t.value)
mesh=mesh, value=self.value(t=float(t))
)
else:
self.value_fenics = fem.Function(function_space)
Expand All @@ -119,19 +119,6 @@ def create_value(
)
self.value_fenics.interpolate(self.bc_expr)

def create_formulation(self, dofs, function_space):
"""Applies the boundary condition
Args:
dofs (numpy.ndarray): the degrees of freedom of surface facets
function_space (dolfinx.fem.FunctionSpace): the function space
"""
form = fem.dirichletbc(
value=self.value_fenics,
dofs=dofs,
V=function_space,
)
return form

def update(self, t):
"""Updates the boundary condition value
Expand Down
96 changes: 59 additions & 37 deletions festim/hydrogen_transport_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,45 +246,67 @@ def define_boundary_conditions(self):
# if name of species is given then replace with species object
bc.species = F.find_species_from_name(bc.species, self.species)
if isinstance(bc, F.DirichletBC):
if (len(self.species) > 1) and (
not isinstance(bc.value, (int, float, fem.Constant))
):
bc_dofs = bc.define_surface_subdomain_dofs(
facet_meshtags=self.facet_meshtags,
mesh=self.mesh,
function_space=(
bc.species.sub_function_space,
bc.species.collapsed_function_space,
),
)
bc.create_value(
mesh=self.mesh.mesh,
temperature=self.temperature,
function_space=bc.species.collapsed_function_space,
t=self.t,
)
else:
bc_dofs = bc.define_surface_subdomain_dofs(
facet_meshtags=self.facet_meshtags,
mesh=self.mesh,
function_space=bc.species.sub_function_space,
)
bc.create_value(
mesh=self.mesh.mesh,
temperature=self.temperature,
function_space=bc.species.sub_function_space,
t=self.t,
)
if (len(self.species) == 1) and (
isinstance(bc.value_fenics, (fem.Function))
):
form = bc.create_formulation(dofs=bc_dofs, function_space=None)
else:
form = bc.create_formulation(
dofs=bc_dofs, function_space=bc.species.sub_function_space
)
form = self.create_dirichletbc_form(bc)
self.bc_forms.append(form)

def create_dirichletbc_form(self, bc):
"""Creates a dirichlet boundary condition form
Args:
bc (festim.DirichletBC): the boundary condition
Returns:
dolfinx.fem.bcs.DirichletBC: A representation of
the boundary condition for modifying linear systems.
"""
# create value_fenics
function_space_value = None

if callable(bc.value):
# if bc.value is a callable then need to provide a functionspace

if len(self.species) == 1:
function_space_value = bc.species.sub_function_space
else:
function_space_value = bc.species.collapsed_function_space

bc.create_value(
mesh=self.mesh.mesh,
temperature=self.temperature,
function_space=function_space_value,
t=self.t,
)

# get dofs
if len(self.species) > 1 and isinstance(bc.value_fenics, (fem.Function)):
function_space_dofs = (
bc.species.sub_function_space,
bc.species.collapsed_function_space,
)
else:
function_space_dofs = bc.species.sub_function_space

bc_dofs = bc.define_surface_subdomain_dofs(
facet_meshtags=self.facet_meshtags,
mesh=self.mesh,
function_space=function_space_dofs,
)

# create form
if len(self.species) == 1 and isinstance(bc.value_fenics, (fem.Function)):
form = fem.dirichletbc(
value=bc.value_fenics,
dofs=bc_dofs,
# no need to pass the functionspace since value_fenics is already a Function
)
else:
form = fem.dirichletbc(
value=bc.value_fenics,
dofs=bc_dofs,
V=bc.species.sub_function_space,
)
return form

def create_formulation(self):
"""Creates the formulation of the model"""
if len(self.sources) > 1:
Expand Down
5 changes: 3 additions & 2 deletions test/test_dirichlet_bc.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,13 @@ def test_value_callable_x_t_T():
assert np.isclose(computed_value, expected_value)


def test_callable_t_only():
@pytest.mark.parametrize("value", [lambda t: t, lambda t: 1.0 + t])
def test_callable_t_only(value):
"""Test that the value attribute can be a callable function of t only"""

subdomain = F.SurfaceSubdomain1D(1, x=1)
vol_subdomain = F.VolumeSubdomain1D(1, borders=[0, 1], material=dummy_mat)
value = lambda t: 1.0 + t
# value = lambda t: 1.0 + t
species = F.Species("test")

bc = F.DirichletBC(subdomain, value, species)
Expand Down

0 comments on commit 6de35aa

Please sign in to comment.