Hello,
I am wondering how to apply time dependent multiple boundary conditions on dolfinx.
I used to define “Expressions” for both Dirichlet and Neumann time dependent boundary conditions in dolfin Legacy see MWE below:
from dolfin import *
import numpy as np
mesh = IntervalMesh(2, 0, 1)
V = FunctionSpace(mesh, FiniteElement('CG', mesh.ufl_cell(), degree=1))
u = Function(V, name = "displacement")
#Dirichlet BC
final_loading = 1.
loading = Expression("t", t=final_loading, degree=0)
def l_boundary(x, on_boundary):
return near(x[0], 0.)
current_l_bc = Expression("0.1*t", t=loading, degree=0)
l_bc = DirichletBC(V, current_l_bc, l_boundary)
def r_boundary(x, on_boundary):
return near(x[0], 1)
current_r_bc = Expression("0.2*t", t=loading, degree=0)
r_bc = DirichletBC(V, current_r_bc, r_boundary)
#Neumann BC
body_f_magnitude = Expression("0.3*t", t=loading, degree=0)
v = TestFunction(V)
L = body_f_magnitude * v * ds
load_steps = np.linspace(0, final_loading, 10)
for t in load_steps:
loading.t = t
l_bc.apply(u.vector())
r_bc.apply(u.vector())
print("Displacement vector", u.vector().get_local())
print("Time dependant lhs", assemble(L).get_local())
print("Loading parameter", loading.t)
So it was very easy to update all the BCs at once inside the time stepping loop writing loading.t = t.
On DolfinX I would also like to set my Dirichlet BC as well as the linear form using a single load parameter “t”. Whereas there is no issue with the lhs, it seems that it’s not possible to set a Dirichlet BC with a product of two Constants see the MWE:
from ufl import dot, TestFunction, inner, ds, FiniteElement
from dolfinx import fem
from dolfinx.fem import Function, assemble, form, Constant, FunctionSpace, locate_dofs_topological, set_bc, assemble_vector
from dolfinx.mesh import create_unit_interval, locate_entities_boundary
import numpy as np
from petsc4py.PETSc import ScalarType
from mpi4py import MPI
mesh = create_unit_interval(MPI.COMM_WORLD, 2)
V = FunctionSpace(mesh, ("CG", 1))
u = Function(V, name = "displacement")
fdim = mesh.topology.dim - 1
#Dirichlet BC
def l_boundary(x):
return np.isclose(x[0], 0)
def r_boundary(x):
return np.isclose(x[0], 1)
l_bc_facets = locate_entities_boundary(mesh, fdim, l_boundary)
r_bc_facets = locate_entities_boundary(mesh, fdim, r_boundary)
l_magnitude = Constant(mesh, ScalarType(0.1))
r_magnitude = Constant(mesh, ScalarType(0.2))
final_loading = 1
loading = Constant(mesh, ScalarType(final_loading))
current_l_bc = l_magnitude * loading
current_r_bc = r_magnitude * loading
#What i would like to do
l_bc = fem.dirichletbc(current_l_bc, locate_dofs_topological(V, fdim, l_bc_facets), V)
r_bc = fem.dirichletbc(current_r_bc, locate_dofs_topological(V, fdim, r_bc_facets), V)
#Neumann BC
body_f_magnitude = Constant(mesh, ScalarType(0.3))
v = TestFunction(V)
L = body_f_magnitude * loading * v * ds
load_steps = np.linspace(0, final_loading, 10)
for t in load_steps:
#So that i would update my Dirichlet BC like this
loading.value = t
set_bc(u.vector, [l_bc, r_bc])
print("Displacement vector", u.vector.array)
print("Time dependant lhs", assemble_vector(fem.form(L)).array)
print("Loading parameter", loading.value)
Which raise the following error:
File "/home/bouteillerp/Bureau/Time_dependent_Bcs_Dolfinx.py", line 41, in <module>
l_bc = fem.dirichletbc(current_l_bc, locate_dofs_topological(V, fdim, l_bc_facets), V)
File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/fem/bcs.py", line 179, in dirichletbc
raise AttributeError("Boundary condition value must have a dtype attribute.")
AttributeError: Boundary condition value must have a dtype attribute.
AttributeError: Boundary condition value must have a dtype attribute.
Is there any elegant way to define multiple boundary conditions, parameterized by a single scalar t, without updating all of them manually ?
Thank you