Define DirichletBC for a Vector Function

Hello everybody,
I want to solve a 2-D linear elasticity problem in the area [0,1]X[0,1], which has Dirichlet boundary condition:
u_x(0,0) = u_y(0,0) =0, u_y(x,0) = 0, u_y(x,1) = -0.001
where u_x(x,y), u_y(x,y) represent the displacement in x, y direction of point (x,y).

So, how should I define this DirichletBC in FEniCS?

Thanks very much!

See for instance: Bitbucket
on how to set Dirichlet conditions on sub spaces. If you use dolfinx, consider:
Component-wise Dirichlet BC — FEniCSx tutorial

Thanks very much! But I am not clever and still have problems. I think I do not use dolfinx. And I still do not know how to set ux instead of u as boundary condition after reading the first instance.
I try to write it by myself:
from fenics import *

L = 1
nu = 0.499
mu = 1
lambda_ = mu 2 nu/(1-2*nu)

pixel = 1
mesh = UnitSquareMesh(pixel, pixel)
V = VectorFunctionSpace(mesh, ‘P’, 1)

V0 = V.sub(0).collapse()
uy_D_y0 = Function(V0)
with uy_D_y0.vector.localForm() as uy_D_y0_loc:
uy_D_y0_loc.set(0)

tol = 1E-14
def lowside(x, on_boundary):
return on_boundary and abs(x[0])>tol and abs(x[1])<tol
boundary_y0 = locate_dofs_geometrical((V.sub(0), V0), lowside)
bc_y0 = DirichletBC(uy_D_y0, boundary_y0, V.sub(0))

uy_D_yL = Function(V0)
with uy_D_yL.vector.localForm() as uy_D_yL_loc:
uy_D_yL_loc.set(-0.2)
def highside(x, on_boundary):
return on_boundary and abs(x[1]-L)<tol
boundary_yL = locate_dofs_geometrical((V.sub(0), V0), highside)
bc_yL = DirichletBC(uy_D_yL, boundary_yL, V.sub(0))

def boundary_x0y0(x, on_boundary):
return on_bounday and abs(x[0])<tol and abs(x[1])<tol
bc_x0y0 = DirichletBC(V, Constant(0, 0), boundary_x0y0)
bcs = [bc_x0y0,bc_y0,bc_yL]

def epsilon(u):
return 0.5*(nabla_grad(u) + nabla_grad(u).T)

def sigma(u):
return lambda_ nabla_div(u) Identity(d) + 2 mu epsilon(u)

u = TrialFunction(V)
d = u.geometric_dimension()
v = TestFunction(V)
f = Constant((0, 0))
T = Constant((0, 0))
a = inner(sigma(u), epsilon(v))*dx
L = dot(f, v)*dx +dot(T, v)*ds

u = Function(V)
solve(a == L, u, bcs)

plot(u, title=‘Displacement’, mode=‘displacement’)

But there is an error:
‘function’ object has no attribute ‘localForm’

I will appreciate it very much if you can have some comments on my poor code :slight_smile:

The code you have posted is a mix between dolfinx and dolfin. You need to follow either the first link I sent (Taylor hood, using dolfin)
or the second one if you are going to use dolfinx.
Secondly, for further code snippets, please use 3x` encapsulation to ensure proper formatting.

Thank you for pointing out the error. I decide to use dolfinx. I try to install dolfinx in ubuntu 20.04 by

sudo add-apt-repository ppa:fenics-packages/fenics
sudo apt-get update 
sudo apt-get install fenicsx

but I failed. When I run

from dolfinx.fem import Constant, DirichletBC, Function, FunctionSpace, LinearProblem, locate_dofs_geometrical
from dolfinx.generation import RectangleMesh
from dolfinx.mesh import CellType
from ufl import Identity, Measure, TestFunction, TrialFunction, VectorElement, dot, dx, inner, grad, nabla_div, sym
from mpi4py import MPI

in jupyter notebook, it comes that

ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-2-1cbf2a47bbed> in <module>
----> 1 from dolfinx.fem import Constant, DirichletBC, Function, FunctionSpace, LinearProblem, locate_dofs_geometrical
      2 from dolfinx.generation import RectangleMesh
      3 from dolfinx.mesh import CellType
      4 from ufl import Identity, Measure, TestFunction, TrialFunction, VectorElement, dot, dx, inner, grad, nabla_div, sym
      5 from mpi4py import MPI

ModuleNotFoundError: No module named 'dolfinx'

So, I am confused how to install dolfinx. Can you help me? Thanks very much!

What system are you running on? Ubuntu 18.04 for instance is not supported: Error when building Basix from source - #4 by dparsons

I use ubuntu 20.04 as mentioned. It seems there is no problem with

sudo apt-get install fenicsx

Could you list the output of apt-get install fenicsx and do also call pip3 list?


This image consists all the packages which name has ‘fenics’. Is it ok?

So the package is there, could you try calling python3 -c “import dolfinx;print(dolfinx.__version__)”


That’s the result.

That means that dolfinx is installed. Did you run python2.7 when you got the error message above?

Note that the tutorial I linked to above is compatible with the main branch of dolfinx. To see the compatible version for 0.3.0 see; dolfinx-tutorial/component_bc.ipynb at v0.3.0 · jorgensd/dolfinx-tutorial · GitHub

Thanks very much. I find I do not install dolfinx in the docker I use. But I have one more doubt. I refer to this GitHub - FEniCS/dolfinx: Next generation FEniCS problem solving environment and create a jupyter notebook with

docker run --init -ti -p 8888:8888 dolfinx/lab:latest # Access at http://localhost:8888

Then I find that the version of dolfinx is 0.3.1 instead of 0.3.0. And when I try

import dolfinx
import ufl
import numpy as np
from mpi4py import MPI
from dolfinx.cpp.mesh import CellType

mesh = dolfinx.RectangleMesh(MPI.COMM_WORLD, np.array([[0,0,0],[L, H,0]]), [30,30], cell_type=CellType.triangle)
element = ufl.VectorElement("CG", mesh.ufl_cell(), 1)
V = dolfinx.FunctionSpace(mesh, element)

It comes out

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/tmp/ipykernel_15/500810691.py in <module>
      7 L = 1
      8 
----> 9 mesh = dolfinx.RectangleMesh(MPI.COMM_WORLD, np.array([[0,0,0],[L, L,0]]), [30,30], cell_type=CellType.triangle)
     10 element = ufl.VectorElement("CG", mesh.ufl_cell(), 1)
     11 V = dolfinx.FunctionSpace(mesh, element)

AttributeError: module 'dolfinx' has no attribute 'RectangleMesh'

So, is there any tutorial for 0.3.1 or how can I install the version 0.3.0?
Thanks very much!

Hi dokken, I try to write the code again

import numpy as np
from mpi4py import MPI
from ufl import Identity, Measure, TestFunction, TrialFunction, VectorElement, dot, dx, inner, grad, nabla_div, sym

from dolfinx.generation import RectangleMesh
from dolfinx.mesh import CellType, locate_entities_boundary
from dolfinx.fem import (Constant, DirichletBC, Function, LinearProblem, FunctionSpace, VectorFunctionSpace, 
                         locate_dofs_geometrical)

L = 1
nu = 0.499
mu = 1
lambda_ = mu*2*nu/(1-2*nu)
pixel = 1

mesh = RectangleMesh(MPI.COMM_WORLD, np.array([[0, 0, 0], [L, L, 0]]), [pixel, pixel], cell_type=CellType.quadrilateral)
V = VectorFunctionSpace(mesh, ("CG", 1))

Vy = V.sub(1).collapse()
uDy_high = Function(Vy)
with uDy_high.vector.localForm() as uDy_high_loc:
    uDy_high_loc.set(-0.2*L)
                                               
def highside(x):
    return np.logical_and(np.isclose(x[1], L), x[0]<L)
boundary_high = locate_dofs_geometrical((V.sub(1), Vy), highside)
bch = DirichletBC(uDy_high, boundary_high, V.sub(1))
                                               
uDy_low = Function(Vy)
with uDy_low.vector.localForm() as uDy_low_loc:
    uDy_low_loc.set(0)
                                               
def lowside(x):
    return np.logical_and(np.isclose(x[1], 0), x[0]<L)
boundary_low = locate_dofs_geometrical((V.sub(1), Vy), lowside)
bcl = DirichletBC(uDy_low, boundary_low, V.sub(1))

Vx = V.sub(0).collapse()
uDx = Function(Vx)
with uDx.vector.localForm() as uDx_loc:
    uDx_loc.set(0)
                                               
def origin(x):
    tol = 1E-14
    return np.logical_and(np.isclose(x[0], 0), x[1]<tol)
boundary_origin = locate_dofs_geometrical((V.sub(0), Vx), origin)
bco = DirichletBC(uDx, boundary_origin, V.sub(0))
                                               
bcs = [bco, bcl, bch]
                                               
def epsilon(u):
    return sym(grad(u)) 
def sigma(u):
    return lambda_ * nabla_div(u) * Identity(u.geometric_dimension()) + 2*mu*epsilon(u)

u = TrialFunction(V)
v = TestFunction(V)
f = Constant(mesh, (0, 0))
T = Constant(mesh, (0, 0))

ds = Measure("ds", domain=mesh)
a = inner(sigma(u), epsilon(v)) * dx
L = dot(f, v) * dx + dot(T, v) * ds

problem = LinearProblem(a, L, bcs=bcs, petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
uh = problem.solve()

But I get the error

ArityMismatch                             Traceback (most recent call last)
/tmp/ipykernel_15/3595350227.py in <module>
     63 L = dot(f, v) * dx + dot(T, v) * ds
     64 
---> 65 problem = LinearProblem(a, L, bcs=bcs, petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
     66 uh = problem.solve()
     67 

/usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/fem/problem.py in __init__(self, a, L, bcs, u, petsc_options, form_compiler_parameters, jit_parameters)
     61         self._A = fem.create_matrix(self._a)
     62 
---> 63         self._L = fem.Form(L, form_compiler_parameters=form_compiler_parameters, jit_parameters=jit_parameters)
     64         self._b = fem.create_vector(self._L)
     65 

/usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/fem/form.py in __init__(self, form, dtype, form_compiler_parameters, jit_parameters)
     57         else:
     58             raise RuntimeError(f"Unsupported scalar type {dtype} for Form.")
---> 59         self._ufc_form, module, self._code = jit.ffcx_jit(
     60             mesh.comm,
     61             form,

/usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/jit.py in mpi_jit(comm, *args, **kwargs)
     54         # Just call JIT compiler when running in serial
     55         if comm.size == 1:
---> 56             return local_jit(*args, **kwargs)
     57 
     58         # Default status (0 == ok, 1 == fail)

/usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/jit.py in ffcx_jit(ufl_object, form_compiler_parameters, jit_parameters)
    207     # Switch on type and compile, returning cffi object
    208     if isinstance(ufl_object, ufl.Form):
--> 209         r = ffcx.codegeneration.jit.compile_forms([ufl_object], parameters=p_ffcx, **p_jit)
    210     elif isinstance(ufl_object, ufl.FiniteElementBase):
    211         r = ffcx.codegeneration.jit.compile_elements([ufl_object], parameters=p_ffcx, **p_jit)

/usr/local/lib/python3.9/dist-packages/ffcx/codegeneration/jit.py in compile_forms(forms, parameters, cache_dir, timeout, cffi_extra_compile_args, cffi_verbose, cffi_debug, cffi_libraries)
    164             decl += form_template.format(name=name)
    165 
--> 166         impl = _compile_objects(decl, forms, form_names, module_name, p, cache_dir,
    167                                 cffi_extra_compile_args, cffi_verbose, cffi_debug, cffi_libraries)
    168     except Exception:

/usr/local/lib/python3.9/dist-packages/ffcx/codegeneration/jit.py in _compile_objects(decl, ufl_objects, object_names, module_name, parameters, cache_dir, cffi_extra_compile_args, cffi_verbose, cffi_debug, cffi_libraries)
    228     # JIT uses module_name as prefix, which is needed to make names of all struct/function
    229     # unique across modules
--> 230     _, code_body = ffcx.compiler.compile_ufl_objects(ufl_objects, prefix=module_name, parameters=parameters)
    231 
    232     ffibuilder = cffi.FFI()

/usr/local/lib/python3.9/dist-packages/ffcx/compiler.py in compile_ufl_objects(ufl_objects, object_names, prefix, parameters, visualise)
     96     # Stage 1: analysis
     97     cpu_time = time()
---> 98     analysis = analyze_ufl_objects(ufl_objects, parameters)
     99     _print_timing(1, time() - cpu_time)
    100 

/usr/local/lib/python3.9/dist-packages/ffcx/analysis.py in analyze_ufl_objects(ufl_objects, parameters)
     60     if isinstance(ufl_objects[0], ufl.form.Form):
     61         forms = ufl_objects
---> 62         form_data = tuple(_analyze_form(form, parameters) for form in forms)
     63 
     64         # Extract unique elements across forms

/usr/local/lib/python3.9/dist-packages/ffcx/analysis.py in <genexpr>(.0)
     60     if isinstance(ufl_objects[0], ufl.form.Form):
     61         forms = ufl_objects
---> 62         form_data = tuple(_analyze_form(form, parameters) for form in forms)
     63 
     64         # Extract unique elements across forms

/usr/local/lib/python3.9/dist-packages/ffcx/analysis.py in _analyze_form(form, parameters)
    166 
    167     # Compute form metadata
--> 168     form_data = ufl.algorithms.compute_form_data(
    169         form,
    170         do_apply_function_pullbacks=True,

/usr/local/lib/python3.9/dist-packages/ufl/algorithms/compute_form_data.py in compute_form_data(form, do_apply_function_pullbacks, do_apply_integral_scaling, do_apply_geometry_lowering, preserve_geometry_types, do_apply_default_restrictions, do_apply_restrictions, do_estimate_degrees, do_append_everywhere_integrals, complex_mode)
    405     preprocessed_form = reconstruct_form_from_integral_data(self.integral_data)
    406 
--> 407     check_form_arity(preprocessed_form, self.original_form.arguments(), complex_mode)  # Currently testing how fast this is
    408 
    409     # TODO: This member is used by unit tests, change the tests to

/usr/local/lib/python3.9/dist-packages/ufl/algorithms/check_arities.py in check_form_arity(form, arguments, complex_mode)
    175 def check_form_arity(form, arguments, complex_mode=False):
    176     for itg in form.integrals():
--> 177         check_integrand_arity(itg.integrand(), arguments, complex_mode)

/usr/local/lib/python3.9/dist-packages/ufl/algorithms/check_arities.py in check_integrand_arity(expr, arguments, complex_mode)
    168         for arg, conj in arg_tuples:
    169             if arg.number() == 0 and not conj:
--> 170                 raise ArityMismatch("Failure to conjugate test function in complex Form")
    171             elif arg.number() > 0 and conj:
    172                 raise ArityMismatch("Argument {0} is spuriously conjugated in complex Form".format(arg))

ArityMismatch: Failure to conjugate test function in complex Form

So, would you please tell me if there is any error in my defination of boundary conditions(especially at the point(0,0)) or other parts? :slight_smile:

You are running the complex mode of dolfinx (support for complex Numbers). Then all ufl.dot hasto be replaced by ufl.inner in the definition of a and L

Thanks. I replace all the dot by inner, but there is still an error

TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_15/3789491759.py in <module>
     63 L = inner(f, v) * dx + inner(T, v) * ds
     64 
---> 65 problem = LinearProblem(a, L, bcs=bcs, petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
     66 uh = problem.solve()
     67 

/usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/fem/problem.py in __init__(self, a, L, bcs, u, petsc_options, form_compiler_parameters, jit_parameters)
     61         self._A = fem.create_matrix(self._a)
     62 
---> 63         self._L = fem.Form(L, form_compiler_parameters=form_compiler_parameters, jit_parameters=jit_parameters)
     64         self._b = fem.create_vector(self._L)
     65 

/usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/fem/form.py in __init__(self, form, dtype, form_compiler_parameters, jit_parameters)
     89 
     90         ffi = cffi.FFI()
---> 91         self._cpp_object = create_form(dtype)(ffi.cast("uintptr_t", ffi.addressof(self._ufc_form)),
     92                                               function_spaces, coeffs,
     93                                               [c._cpp_object for c in form.constants()], subdomains,

TypeError: create_form_complex128(): incompatible function arguments. The following argument types are supported:
    1. (arg0: int, arg1: List[dolfinx::fem::FunctionSpace], arg2: List[dolfinx.cpp.fem.Function_complex128], arg3: List[dolfinx.cpp.fem.Constant_complex128], arg4: Dict[dolfinx::fem::IntegralType, dolfinx.cpp.mesh.MeshTags_int32], arg5: dolfinx.cpp.mesh.Mesh) -> dolfinx.cpp.fem.Form_complex128

Invoked with: <cdata 'uintptr_t' 139772411077632>, [<dolfinx.cpp.fem.FunctionSpace object at 0x7f1f12d89370>], [], [<dolfinx.cpp.fem.Constant_float64 object at 0x7f1f4cf3fbb0>, <dolfinx.cpp.fem.Constant_float64 object at 0x7f1f12d62270>], {<IntegralType.cell: 0>: None, <IntegralType.exterior_facet: 1>: None, <IntegralType.interior_facet: 2>: None, <IntegralType.vertex: 3>: None}, <dolfinx.mesh.Mesh object at 0x7f1f12d96220>

Change this to:

from petsc4py import PETSc
f = Constant(mesh, PETSc.ScalarType((0, 0)))
T = Constant(mesh, PETSc.ScalarType((0, 0)))

I got the solution successfully. Thank you very much for these days’ patient and accurate help!

Hi dokken, sorry for bothering you again. Would you please tell me what I should do if I want to change lambda_ and mu as a function of the position (x,y) instead of a constant?:slight_smile:

See for instance: Implementation — FEniCSx tutorial