The code is
import time
import cffi
import dolfinx.fem.petsc as petsc
import numpy as np
import ufl
from dolfinx import fem, io, mesh, plot
from mpi4py import MPI
from petsc4py.lib.PETSc import ScalarType
from ufl import div, ds, dx, grad, inner, rank
class LocalAssembler():
def __init__(self, form):
self.form = fem.form(form)
self.update_coefficients()
self.update_constants()
subdomain_ids = self.form.integral_ids(fem.IntegralType.cell)
assert(len(subdomain_ids) == 1)
assert(subdomain_ids[0] == -1)
is_complex = np.issubdtype(ScalarType, np.complexfloating)
nptype = "complex128" if is_complex else "float64"
self.kernel = getattr(self.form.ufcx_form.integrals(fem.IntegralType.cell)[0], f"tabulate_tensor_{nptype}")
self.active_cells = self.form.domains(fem.IntegralType.cell, -1)
assert len(self.form.function_spaces) == self.form.rank
self.local_shape = [0 for _ in range(self.form.rank)]
for i, V in enumerate(self.form.function_spaces):
self.local_shape[i] = V.dofmap.dof_layout.block_size * V.dofmap.dof_layout.num_dofs
e0 = self.form.function_spaces[0].element
if self.form.rank == 1:
e1 = self.form.function_spaces[0].element
elif self.form.rank == 2:
e1 = self.form.function_spaces[1].element
else:
raise RuntimeError(f"Assembly for tensor of tensor of {rank=} is not supported")
needs_transformation_data = e0.needs_dof_transformations or e1.needs_dof_transformations or \
self.form.needs_facet_permutations
if needs_transformation_data:
raise NotImplementedError("Dof transformations not implemented")
self.ffi = cffi.FFI()
V = self.form.function_spaces[0]
self.x_dofs = V.mesh.geometry.dofmap
self.local_tensor = np.zeros(self.local_shape, dtype=ScalarType)
def update_coefficients(self):
self.coeffs = fem.assemble.pack_coefficients(self.form)[(fem.IntegralType.cell, -1)]
def update_constants(self):
self.consts = fem.assemble.pack_constants(self.form)
def update(self):
self.update_coefficients()
self.update_constants()
def assemble(self, i:int):
x = self.form.function_spaces[0].mesh.geometry.x
x_dofs = self.x_dofs.links(i)
geometry = np.zeros((len(x_dofs), 3), dtype=np.float64)
geometry[:, :] = x[x_dofs]
facet_index = np.zeros(0, dtype=np.intc)
facet_perm = np.zeros(0, dtype=np.uint8)
if self.coeffs.shape == (0, 0):
coeffs = np.zeros(0, dtype=ScalarType)
else:
coeffs = self.coeffs[i,:]
ffi_fb = self.ffi.from_buffer
self.local_tensor.fill(0)
self.kernel(ffi_fb(self.local_tensor), ffi_fb(coeffs), ffi_fb(self.consts), ffi_fb(geometry),
ffi_fb(facet_index), ffi_fb(facet_perm), self.ffi.NULL,)
return self.local_tensor
N = 20
msh = mesh.create_box(MPI.COMM_WORLD, [np.array([0.0, 0.0, 0.0]),
np.array([2.0, 1.0, 1.0])], [N, N, N],
mesh.CellType.tetrahedron)
Q = fem.functionspace(msh, ("DG", 2))
p = ufl.TrialFunction(Q)
q = ufl.TestFunction(Q)
a = inner(p, q) *dx
lhs_assembler = LocalAssembler(a)
Which is from Element-wise post-processing
Then when I try to run it in FEnicsx, errors say that
Traceback (most recent call last):
File "/home/a/PycharmProjects/Explode/main.py", line 89, in <module>
lhs_assembler = LocalAssembler(a)
^^^^^^^^^^^^^^^^^
File "/home/a/PycharmProjects/Explode/main.py", line 17, in __init__
self.update_coefficients()
File "/home/a/PycharmProjects/Explode/main.py", line 50, in update_coefficients
self.coeffs = fem.assemble.pack_coefficients(self.form)[(fem.IntegralType.cell, -1)]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyError: (_IntegralType.cell, -1)
How to fix this
########################EDIT##################################################
I edit the code, then the latest code is
class LocalAssembler():
def __init__(self, form, integral_type: fem.IntegralType =fem.IntegralType.cell):
self.form = fem.form(form)
self.integral_type = integral_type
self.update_coefficients()
self.update_constants()
self.local_shape = [0 for _ in range(self.form.rank)]
self.local_tensor = np.zeros(self.local_shape, dtype=ScalarType)
# subdomain_ids = self.form.integral_ids(integral_type)
# assert(len(subdomain_ids) == 1)
# assert(subdomain_ids[0] == -1)
is_complex = np.issubdtype(ScalarType, np.complexfloating)
nptype = "complex128" if is_complex else "float64"
o_s = self.form.ufcx_form.form_integral_offsets[_type_to_offset_index[integral_type]]
o_e = self.form.ufcx_form.form_integral_offsets[_type_to_offset_index[integral_type]+1]
assert o_e - o_s == 1
self.kernel = getattr(self.form.ufcx_form.form_integrals[o_s], f"tabulate_tensor_{nptype}")
self.active_cells = self.form._cpp_object.domains(integral_type, 0)
#assert len(self.form.function_spaces) == 2
self.local_shape = [0,0]
for i, V in enumerate(self.form.function_spaces):
self.local_shape[i] = V.dofmap.dof_layout.block_size * V.dofmap.dof_layout.num_dofs
self.local_shape = [0 for _ in range(self.form.rank)]
for i, V in enumerate(self.form.function_spaces):
self.local_shape[i] = V.dofmap.dof_layout.block_size * V.dofmap.dof_layout.num_dofs
e0 = self.form.function_spaces[0].element
if self.form.rank == 1:
e1 = self.form.function_spaces[0].element
elif self.form.rank == 2:
e1 = self.form.function_spaces[1].element
else:
raise RuntimeError(f"Assembly for tensor of tensor of {rank=} is not supported")
needs_transformation_data = e0.needs_dof_transformations or e1.needs_dof_transformations or \
self.form._cpp_object.needs_facet_permutations
if needs_transformation_data:
raise NotImplementedError("Dof transformations not implemented")
#e0 = self.form.function_spaces[0].element
#e1 = self.form.function_spaces[1].element
self.ffi = cffi.FFI()
V = self.form.function_spaces[0]
self.x_dofs = V.mesh.geometry.dofmap
def update_coefficients(self):
self.coeffs = fem.assemble.pack_coefficients(self.form)[(self.integral_type, 0)]
def update_constants(self):
self.consts = fem.assemble.pack_constants(self.form)
def update(self):
self.update_coefficients()
self.update_constants()
def assemble_matrix(self, i:int, local_index:int = 0):
x = self.form.function_spaces[0].mesh.geometry.x
x_dofs = self.x_dofs[i]
geometry = np.zeros((len(x_dofs), 3), dtype=np.float64)
geometry[:, :] = x[x_dofs]
#A_local = np.zeros((self.local_shape[0], self.local_shape[0]), dtype=ScalarType)
facet_index = np.array([local_index], dtype=np.intc)
facet_perm = np.zeros(0, dtype=np.uint8)
if self.coeffs.shape == (0, 0):
coeffs = np.zeros(0, dtype=ScalarType)
else:
coeffs = self.coeffs[i,:]
ffi_fb = self.ffi.from_buffer
self.local_tensor.fill(0)
self.kernel(ffi_fb(self.local_tensor), ffi_fb(coeffs), ffi_fb(self.consts), ffi_fb(geometry),
ffi_fb(facet_index), ffi_fb(facet_perm), self.ffi.NULL, )
return self.local_tensor
then an error
Traceback (most recent call last):
File "/home/a/PycharmProjects/Explode/main.py", line 114, in <module>
A = lhs_assembler.assemble_matrix(cell)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/a/PycharmProjects/Explode/main.py", line 87, in assemble_matrix
self.kernel(ffi_fb(self.local_tensor), ffi_fb(coeffs), ffi_fb(self.consts), ffi_fb(geometry),
TypeError: implicit cast from 'char *' to a different pointer type: (check that the types are as you expect; use an explicit ffi.cast() if they are correct)
occurs, how to fix this?