diff --git a/festim/boundary_conditions/dirichlet_bc.py b/festim/boundary_conditions/dirichlet_bc.py index cd334c483..6b31ab22e 100644 --- a/festim/boundary_conditions/dirichlet_bc.py +++ b/festim/boundary_conditions/dirichlet_bc.py @@ -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) @@ -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 diff --git a/festim/hydrogen_transport_problem.py b/festim/hydrogen_transport_problem.py index a90f5eb3d..3a45adec7 100644 --- a/festim/hydrogen_transport_problem.py +++ b/festim/hydrogen_transport_problem.py @@ -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: diff --git a/test/test_dirichlet_bc.py b/test/test_dirichlet_bc.py index 065a97b25..c73742c15 100644 --- a/test/test_dirichlet_bc.py +++ b/test/test_dirichlet_bc.py @@ -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)