Dolfinx.mesh.locate_entities(...) unknown after update

hey there, I used some code out of the example for Setting multiple Dirichlet, Neumann, and Robin conditions and encountered a problem after a fenicsx software-update:

The command facets = locate_entities(mesh, fdim, locator) does not work anymore, like many other commands do not as well (they did work before the update).

Now, I get the error message
AttributeError: 'Mesh' object has no attribute 'locate_entities'.
For many other expired commands, I did find other, still valid commands. However, I do not find a command to replace locate_entities

So, does anybody know what is the new command to replace dolfinx.mesh.locate_entities(...)?

Without a minimal code that reproduces the issue, people cannot really help you, as your error message states

which indicates that you are using mesh to define the computational domain, and not the module dolfinx.mesh, which has the function locate_entities (as this is still a function in dolfinx, Ref: https://github.com/FEniCS/dolfinx/search?q=locate_entities&type=)

Hi, I post my script up to the boundary condition part, since I don’t know if any shortcuts cause issues with recreating. I marked the proplematic line with the comment <<<<===== This causes issues!.

Since my problem only came with an software update of Fenicsx using the apt-package-manager, I do also post the printed version details underneath. Thank you so much for looking into this matter!

from dolfinx import *
from mpi4py import MPI
import numpy as np
import matplotlib.pyplot as plt
import ufl
import scipy.io
from petsc4py import PETSc

# mesh = UnitSquareMesh(MPI.COMM_WORLD, nx=1, ny=1, cell_type=cpp.mesh.CellType.quadrilateral) # Does not work either, neither the cell_type "cpp.mesh.CellType.quadrilateral"
# mesh = mesh.create_unit_square(MPI.COMM_WORLD, nx=1, ny=1) # https://docs.fenicsproject.org/dolfinx/main/python/generated/dolfinx.mesh.html#dolfinx.mesh.create_unit_cube
# mesh = UnitCubeMesh(MPI.COMM_WORLD, nx=1, ny=1, nz=1) # keine CellTypes in Docs zu finden für 3d, z.B. mesh.CellType.hexahedron aus Bsp. Hyperelasticity
mesh = mesh.create_unit_cube(MPI.COMM_WORLD, nx=1, ny=1, nz=1)

n = ufl.FacetNormal(mesh)
P = ufl.VectorElement("CG", mesh.ufl_cell(), 1)
R = ufl.TensorElement("DG", mesh.ufl_cell(), 1)
P_wish = ufl.VectorElement("CG", mesh.ufl_cell(), 1)
R_wish = ufl.TensorElement("DG", mesh.ufl_cell(), 1)
mel = ufl.MixedElement([P, R, P_wish, R_wish])
U = fem.FunctionSpace(mesh, mel)

u = fem.Function(U)
(p, F, v, P) = ufl.split(u)
(dv, dP, dp, dF) = ufl.TestFunctions(U)

rho_0=1
mu=1
lamb=1

Psi_fun=lambda F: mu/2*(np.trace(F.T@F)-3)-mu*np.log(np.sqrt(np.linalg.det(F.T@F)))+lamb/2*np.log(np.sqrt(np.linalg.det(F.T@F)))**2
P_fun=lambda F: ufl.dot(F,mu*(ufl.classes.Identity(F.ufl_shape[0])-ufl.inv(ufl.dot(F.T,F)))+lamb*ufl.ln(ufl.sqrt(ufl.classes.Determinant(ufl.dot(F.T,F))))*ufl.inv(ufl.dot(F.T,F)))

u_n = fem.Function(U)
(p_n, F_n, v_n, P_n) = ufl.split(u_n)

# Initial conditions:

def initial_cond(x,y,z):
    return np.eye(F.ufl_shape[0])

def T(x):
    values = np.zeros((mesh.geometry.dim*mesh.geometry.dim, x.shape[1]), dtype=np.float64)
    values[0,:] = 1
    values[4,:] = 1
    values[8,:] = 1
    return values

u.sub(1).interpolate(T)

T = 1.5
N = 300 #3000
dt = float(T / N)

time = np.zeros(N + 1)
v_DBC = np.zeros(N + 1)
q_NBC = np.zeros(N + 1)
Hamiltonian = np.zeros(N + 1)

# Physical Parameters
k_w = 3.0
rho_w = 2.0

boundaries = [(1, lambda x: np.isclose(x[0], 0)),
              (2, lambda x: np.isclose(x[0], 1)),
              (3, lambda x: np.isclose(x[1], 0)),
              (4, lambda x: np.isclose(x[1], 1)),
              (5, lambda x: np.isclose(x[2], 0)),
              (6, lambda x: np.isclose(x[2], 1))]

facet_indices, facet_markers = [], []
fdim = mesh.topology.dim - 1
for (marker, locator) in boundaries:
    facets = mesh.locate_entities(mesh, fdim, locator) # <<<<===== This causes issues!
    facets = mesh.locate_entities(mesh, fdim, locator)
    facet_indices.append(facets)
    facet_markers.append(np.full(len(facets), marker))
facet_indices = np.array(np.hstack(facet_indices), dtype=np.int32)
facet_markers = np.array(np.hstack(facet_markers), dtype=np.int32)
sorted_facets = np.argsort(facet_indices)
facet_tag = MeshTags(mesh, fdim, facet_indices[sorted_facets], facet_markers[sorted_facets])

ds = ufl.Measure("ds", domain=mesh, subdomain_data=facet_tag)
ds_Dirichlet=ds(0)+ds(2)
ds_Neumann=ds(1)+ds(3)

Software version:

$ apt-cache madison fenicsx
   fenicsx | 2:0.4.1.2~ppa1~jammy1 | https://ppa.launchpadcontent.net/fenics-packages/fenics/ubuntu jammy/main amd64 Packages
   fenicsx | 2:0.4.1.2~ppa1~jammy1 | https://ppa.launchpadcontent.net/fenics-packages/fenics/ubuntu jammy/main i386 Packages

In python,

import dolfinx
print(dolfinx.__version__)

outputs

0.4.1

With a wildcard import you import the module mesh.
However, you overwrite this by defining

As a rule of thumb, one should never use wildcard imports (as you do not know what you are importing).

Secondly, avoid reusing variable names, as they will cause conflicts such as the aforementioned.

I would suggest either renaming you mesh to domain, or stick with import dolfinx and in turn call dolfinx.fem, dolfinx.mesh etc.

You’re absolutely right, sorry that I did not realize that. Thank you very much for your help!