Cannot follow fenicsx tutorial:

At the very beginning of the fenicsx tutorial Implementation — FEniCSx tutorial, the line

boundary_facets = numpy.flatnonzero(mesh.compute_boundary_facets(domain.topology))

returns the error

AttributeError: module ‘dolfinx.mesh’ has no attribute ‘compute_boundary_facets’

I suspect this occurs because the tutorial deals with dolfinx 0.4.1 while the docker image I use works with dolfinx 0.4.2 and that some things have been renamed.

See: Remove duplicate functionality for finding exterior facets (`mesh:: compute_boundary_facets` removed) by garth-wells · Pull Request #2203 · FEniCS/dolfinx · GitHub

The tutorial will be updated when there is another release.

Hey dokken, I have another trouble with following the tutorial. The command docker run --init -p 8888:8888 -v "$(pwd)":/root/shared dokken92/dolfinx_custom:v0.4.1 returns docker: Error response from daemon: No command specified.
And the command “docker run --init -p 8888:8888 -v “$(pwd)”:/root/shared dokken92/dolfinx_custom:v0.4.1 --name=dolfinx_test0” returns [FATAL tini (7)] exec --name=dolfinx_test0 failed: No such file or directory

I just want to use docker + jupyter notebook and follow the tutorial for now. And be able to restart where I left, when I close the programs.

I’ve just pushed a new version of the docker image dokken92/dolfinx_custom:v0.4.1 that should work.

I still have the same error messages with the commands. One of the commands is taken from the tutorial itself.

Have you pulled the latest image? I.e. docker pull dokken92/dolfinx_custom:v0.4.1

Ah! I think I forgot to update to the new one.
Now it seems to work fine, except that I don’t see the /root/shared folder. I’ll try to figure it out myself. Thanks for all!

Very strange, 2 very similar commands, but only one works as I expect. The commands are

docker run --init -p 8888:8888 -v "$(pwd)":/root/shared --name=testing_tuto dokken92/dolfinx_custom:v0.4.1
and

docker run --init -p 8888:8888 -v "$(pwd)":/root/shared --name=dolfinx_test0 dolfinx/lab:latest

I run them in a terminal opened in a directory on my host machine that I want to share. However only the second command actually opens up a session where I can see the shared files on my host.

I can re-access to the files of the container “testing_tuto”, but I do not see them in my host folder.

Try adding: -w /root/shared. This works for me.

Perfect dokken, that works. Great, once again, thank you for everything!

Hey again dokken. Out of curiosity, is your latest image still inline with the tutorial? I have a problem with the line problem = fem.petsc.LinearProblem(a, L, bcs=[bc], petsc_options={"ksp_type": "preonly", "pc_type": "lu"})

The error is


ArityMismatch Traceback (most recent call last)
Input In [9], in <cell line: 1>()
----> 1 problem = fem.petsc.LinearProblem(a, L, bcs=[bc], petsc_options={“ksp_type”: “preonly”, “pc_type”: “lu”})
2 uh = problem.solve()

File /usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/fem/petsc.py:517, in LinearProblem.init(self, a, L, bcs, u, petsc_options, form_compiler_params, jit_params)
491 def init(self, a: ufl.Form, L: ufl.Form, bcs: typing.List[DirichletBCMetaClass] = ,
492 u: _Function = None, petsc_options={}, form_compiler_params={}, jit_params={}):
493 “”“Initialize solver for a linear variational problem.
494
495 Args:
(…)
515
516 “””
→ 517 self._a = _create_form(a, form_compiler_params=form_compiler_params, jit_params=jit_params)
518 self._A = create_matrix(self._a)
520 self._L = _create_form(L, form_compiler_params=form_compiler_params, jit_params=jit_params)

File /usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/fem/forms.py:139, in form(form, dtype, form_compiler_params, jit_params)
136 return list(map(lambda sub_form: _create_form(sub_form), form))
137 return form
→ 139 return _create_form(form)

File /usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/fem/forms.py:134, in form.._create_form(form)
131 “”“Recursively convert ufl.Forms to dolfinx.fem.Form, otherwise
132 return form argument”“”
133 if isinstance(form, ufl.Form):
→ 134 return _form(form)
135 elif isinstance(form, collections.abc.Iterable):
136 return list(map(lambda sub_form: _create_form(sub_form), form))

File /usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/fem/forms.py:108, in form.._form(form)
105 if mesh is None:
106 raise RuntimeError(“Expecting to find a Mesh in the form.”)
→ 108 ufcx_form, module, code = jit.ffcx_jit(mesh.comm, form,
109 form_compiler_params=form_compiler_params,
110 jit_params=jit_params)
112 # For each argument in form extract its function space
113 V = [arg.ufl_function_space()._cpp_object for arg in form.arguments()]

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

File /usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/jit.py:204, in ffcx_jit(ufl_object, form_compiler_params, jit_params)
202 # Switch on type and compile, returning cffi object
203 if isinstance(ufl_object, ufl.Form):
→ 204 r = ffcx.codegeneration.jit.compile_forms([ufl_object], parameters=p_ffcx, **p_jit)
205 elif isinstance(ufl_object, ufl.FiniteElementBase):
206 r = ffcx.codegeneration.jit.compile_elements([ufl_object], parameters=p_ffcx, **p_jit)

File /usr/local/lib/python3.9/dist-packages/ffcx/codegeneration/jit.py:168, in compile_forms(forms, parameters, cache_dir, timeout, cffi_extra_compile_args, cffi_verbose, cffi_debug, cffi_libraries)
165 for name in form_names:
166 decl += form_template.format(name=name)
→ 168 impl = _compile_objects(decl, forms, form_names, module_name, p, cache_dir,
169 cffi_extra_compile_args, cffi_verbose, cffi_debug, cffi_libraries)
170 except Exception:
171 # remove c file so that it will not timeout next time
172 c_filename = cache_dir.joinpath(module_name + “.c”)

File /usr/local/lib/python3.9/dist-packages/ffcx/codegeneration/jit.py:232, in _compile_objects(decl, ufl_objects, object_names, module_name, parameters, cache_dir, cffi_extra_compile_args, cffi_verbose, cffi_debug, cffi_libraries)
228 import ffcx.compiler
230 # JIT uses module_name as prefix, which is needed to make names of all struct/function
231 # unique across modules
→ 232 _, code_body = ffcx.compiler.compile_ufl_objects(ufl_objects, prefix=module_name, parameters=parameters)
234 ffibuilder = cffi.FFI()
235 ffibuilder.set_source(module_name, code_body, include_dirs=[ffcx.codegeneration.get_include_path()],
236 extra_compile_args=cffi_extra_compile_args, libraries=cffi_libraries)

File /usr/local/lib/python3.9/dist-packages/ffcx/compiler.py:98, 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)
101 # Stage 2: intermediate representation

File /usr/local/lib/python3.9/dist-packages/ffcx/analysis.py:75, in analyze_ufl_objects(ufl_objects, parameters)
72 else:
73 raise TypeError(“UFL objects not recognised.”)
—> 75 form_data = tuple(_analyze_form(form, parameters) for form in forms)
76 for data in form_data:
77 elements += data.unique_sub_elements

File /usr/local/lib/python3.9/dist-packages/ffcx/analysis.py:75, in (.0)
72 else:
73 raise TypeError(“UFL objects not recognised.”)
—> 75 form_data = tuple(_analyze_form(form, parameters) for form in forms)
76 for data in form_data:
77 elements += data.unique_sub_elements

File /usr/local/lib/python3.9/dist-packages/ffcx/analysis.py:156, in _analyze_form(form, parameters)
153 complex_mode = “_Complex” in parameters[“scalar_type”]
155 # Compute form metadata
→ 156 form_data = ufl.algorithms.compute_form_data(
157 form,
158 do_apply_function_pullbacks=True,
159 do_apply_integral_scaling=True,
160 do_apply_geometry_lowering=True,
161 preserve_geometry_types=(ufl.classes.Jacobian,),
162 do_apply_restrictions=True,
163 do_append_everywhere_integrals=False, # do not add dx integrals to dx(i) in UFL
164 complex_mode=complex_mode)
166 # Determine unique quadrature degree, quadrature scheme and
167 # precision per each integral data
168 for id, integral_data in enumerate(form_data.integral_data):
169 # Iterate through groups of integral data. There is one integral
170 # data for all integrals with same domain, itype, subdomain_id
(…)
176
177 # Extract precision

File /usr/local/lib/python3.9/dist-packages/ufl/algorithms/compute_form_data.py:407, 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)
403 # TODO: This is a very expensive check… Replace with something
404 # faster!
405 preprocessed_form = reconstruct_form_from_integral_data(self.integral_data)
→ 407 check_form_arity(preprocessed_form, self.original_form.arguments(), complex_mode) # Currently testing how fast this is
409 # TODO: This member is used by unit tests, change the tests to
410 # remove this!
411 self.preprocessed_form = preprocessed_form

File /usr/local/lib/python3.9/dist-packages/ufl/algorithms/check_arities.py:177, 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)

File /usr/local/lib/python3.9/dist-packages/ufl/algorithms/check_arities.py:170, 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

Seems like the PYTHONPATH has been set to the complex build. Did you do this on purpose?
When I run the docker image on my system, running:

import dolfinx
dolfinx

yields

<module 'dolfinx' from '/usr/local/dolfinx-real/lib/python3.8/dist-packages/dolfinx/__init__.py'>

and

from petsc4py import PETSc
PETSc.ScalarType

yields

numpy.float64

I see. I haven’t changed anything, I don’t even know how to switch between real and complex values. I get <module 'dolfinx' from '/usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/__init__.py'> and numpy.complex128 with your 2 commands…

That is really strange, as I’ve not set those PATHS as the Python path
Could you show the output of:

import sys
import os
sys.path, os.environ["PETSC_ARCH"]

It should yield:

(['/root/shared',
  '',
  '/usr/local/dolfinx-real/lib/python3.8/dist-packages',
  '/usr/local/lib',
  '/root/shared',
  '/usr/lib/python39.zip',
  '/usr/lib/python3.9',
  '/usr/lib/python3.9/lib-dynload',
  '/usr/local/lib/python3.9/dist-packages',
  '/usr/lib/python3/dist-packages'],
 'linux-gnu-real-32')

I get:

([‘/root/shared’,
‘’,
‘/usr/local/dolfinx-complex/lib/python3.8/dist-packages’,
‘/usr/lib/python39.zip’,
‘/usr/lib/python3.9’,
‘/usr/lib/python3.9/lib-dynload’,
‘/usr/local/lib/python3.9/dist-packages’,
‘/usr/lib/python3/dist-packages’],
‘linux-gnu-complex-32’)

I just checked my whole terminal history. I have never typed “complex” in it, as far as I know. I don’t know how I picked the complex version of dolfinx.

Could you try pulling the image again? (I’ve made a minor adjustment, such that you do not have to call -w when you start the container).
I’ll try again on my local system tonight and see if I can reproduce the issue

Thanks dokken, I pulled the image, it works fine, I can access the shared folder with the host just fine, without the -w part.

Ok for the real-complex issue. I hope there is a quick/easy fix…

For your information, I could reproduce this behavior on my desktop pc, too (as well as laptop).
Let me know I could bypass the problem if there’s a quick fix. Thanks!

An easy fix is to change all a*b products with inner(a,b) in the ufl forms, where the test function should be the second argument. I’ll try to resolve this tonight be rebuilding the container with only a real build of DOLFINx.

1 Like

I see. I replaced the single “dot” by “inner”, but this yields the same error (the test function is the 2nd argument). The full code I use is:

from mpi4py import MPI
from dolfinx import mesh
domain = mesh.create_unit_square(MPI.COMM_WORLD, 8, 8, mesh.CellType.quadrilateral)
from dolfinx.fem import FunctionSpace
V = FunctionSpace(domain, ("CG", 1))
from dolfinx import fem
uD = fem.Function(V)
uD.interpolate(lambda x: 1 + x[0]**2 + 2 * x[1]**2)
import numpy
# Create facet to cell connectivity required to determine boundary facets
tdim = domain.topology.dim
fdim = tdim - 1
domain.topology.create_connectivity(fdim, tdim)
boundary_facets = numpy.flatnonzero(mesh.compute_boundary_facets(domain.topology))
boundary_dofs = fem.locate_dofs_topological(V, fdim, boundary_facets)
bc = fem.dirichletbc(uD, boundary_dofs)
import ufl
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)
from petsc4py.PETSc import ScalarType
f = fem.Constant(domain, ScalarType(-6))
a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx
L = f * v * ufl.dx
problem = fem.petsc.LinearProblem(a, L, bcs=[bc], petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
uh = problem.solve()

Is there something else I am missing?