Spatially varying BC

I tried to create define Dirichlet BC as a spatially varying vector. To do so, I defined a SpatialCoordinate and wrapped the function is ufl.as_vector.

The MWE

from dolfinx import mesh
domain = mesh.create_unit_square(MPI.COMM_WORLD, 8, 8, mesh.CellType.quadrilateral)
V = functionspace(domain, ("Lagrange", 1, (domain.geometry.dim,))) #vector function space
x = ufl.SpatialCoordinate(domain)

p0 = fem.Constant(domain, default_scalar_type(1)) #maximal deflection
delta = fem.Constant(domain, default_scalar_type(0.3)) #width

p = p0 * ufl.exp(-delta**2 * (x[0]**2))
u_D  = ufl.as_vector([0,p])

tdim = domain.topology.dim
fdim = tdim - 1
domain.topology.create_connectivity(fdim, tdim)
boundary_facets = mesh.exterior_facet_indices(domain.topology)
boundary_dofs = fem.locate_dofs_topological(V, fdim, boundary_facets)
bc = fem.dirichletbc(u_D, boundary_dofs)

After running this code I get the error

AttributeError: Boundary condition value must have a dtype attribute.

How should I fix this?

Thank you

Interpolate the u_D into the function space of the bc. This is for instance covered in: Diffusion of a Gaussian function โ€” FEniCSx tutorial

1 Like

Thank you!

I also found this helpful

I created a function and interpolated it into the function space, but I got an error. This is a mwe

domain = mesh.create_unit_square(MPI.COMM_WORLD, 8, 8, mesh.CellType.quadrilateral)

V = functionspace(domain, ("Lagrange", 1, (domain.geometry.dim,))) #vector function space
x = ufl.SpatialCoordinate(domain)

def rect( x):
    return [0,(x[0] < 0.6)* (x[0] > 0.4)]

u_D = fem.Function(V)
u_D.interpolate(rect)

def upper_boundary(x):
    return np.isclose(x[1], 1)

fdim = domain.topology.dim - 1

boundary_facets_up = mesh.locate_entities_boundary(domain, fdim, upper_boundary)
dofs_up = fem.locate_dofs_topological(V, fdim, boundary_facets_up)
bc_up = fem.dirichletbc(u_D, dofs_up, V)

and I get the following error:


TypeError Traceback (most recent call last)

/usr/local/lib/python3.10/dist-packages/dolfinx/fem/function.py in interpolate(self, u, cells, nmm_interpolation_data) 452 # u is a Function or Expression (or pointer to one) โ†’ 453 _interpolate(u, cells) 454 except TypeError:


3 frames

TypeError: interpolate(): incompatible function arguments. The following argument types are supported: 1. interpolate(self, f: ndarray[dtype=float64, writable=False, shape=(), order=โ€˜Cโ€™], cells: ndarray[dtype=int32, writable=False, shape=(), order=โ€˜Cโ€™]) โ†’ None 2. interpolate(self, f: ndarray[dtype=float64, writable=False, shape=(, ), order=โ€˜Cโ€™], cells: ndarray[dtype=int32, writable=False, shape=(), order=โ€˜Cโ€™]) โ†’ None 3. interpolate(self, u: dolfinx.cpp.fem.Function_float64, cells: ndarray[dtype=int32, writable=False, shape=(), order=โ€˜Cโ€™], nmm_interpolation_data: tuple[ndarray[dtype=int32, writable=False, shape=(), order=โ€˜Cโ€™], ndarray[dtype=int32, writable=False, shape=(), order=โ€˜Cโ€™], ndarray[dtype=float64, writable=False, shape=(), order=โ€˜Cโ€™], ndarray[dtype=int32, writable=False, shape=(), order=โ€˜Cโ€™]]) โ†’ None 4. interpolate(self, expr: dolfinx.cpp.fem.Expression_float64, cells: ndarray[dtype=int32, writable=False, order=โ€˜Cโ€™]) โ†’ None Invoked with types: dolfinx.cpp.fem.Function_float64, function, ndarray, dolfinx.fem.function.PointOwnershipData

During handling of the above exception, another exception occurred:

ValueError Traceback (most recent call last)

/usr/local/lib/python3.10/dist-packages/dolfinx/fem/function.py in interpolate(self, u, cells, nmm_interpolation_data) 456 assert callable(u) 457 x = _cpp.fem.interpolation_coords(self._V.element, self._V.mesh.geometry, cells) โ†’ 458 self._cpp_object.interpolate(np.asarray(u(x), dtype=self.dtype), cells) # type: ignore 459 460 def copy(self) โ†’ Function:

ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.

Your function rect is wrong. See dolfinx/python/demo/demo_navier-stokes.py at main ยท FEniCS/dolfinx ยท GitHub for an example on how to define it correctly.

(Hint: do not get confused by the newlines, that is a vector expression with two components, look for commas to determine where the first component ends and the second begins)

1 Like

Thank you. I also found another problem: instead of

I should have written

bc_up = fem.dirichletbc(u_D, dofs_up)

(without the vector space)