I am trying to implement a B-bar formulation similar to the one described in B-bar, where the ufl expression describing the strain would need to contain the mean value of the voulmetric strain across the cell.
I have tried the following code using ufl.cell_avg
to calculate the mean volumetric strain
import numpy as np
import dolfinx as dfx
import ufl
from mpi4py import MPI
def b_bar_strain(u):
eps = ufl.sym(ufl.grad(u))
vol = (1/3) * ufl.cell_avg(ufl.tr(eps))
return eps +(vol - (1/3) * ufl.tr(eps)) * ufl.Identity(2)
mesh = dfx.mesh.create_rectangle(MPI.COMM_WORLD,np.array([[0,0],[1., 1.]]), [1,1], cell_type=dfx.mesh.CellType.quadrilateral)
displacement_space = dfx.fem.VectorFunctionSpace(mesh,("CG",1))
stress_space = dfx.fem.TensorFunctionSpace(mesh,("CG",1),shape=(2,2))
stress = dfx.fem.Function(stress_space)
u_= ufl.TestFunction(displacement_space)
stress.vector.array[:] = np.random.random(stress.vector.array.size)
avg = dfx.fem.form(ufl.inner(stress,b_bar_strain(u_))*ufl.dx)
f = dfx.fem.petsc.assemble_vector(avg)
This does not work and I assume it is because of ufl.cell_avg
, because a reduced MWE throws the same error
import numpy as np
import dolfinx as dfx
import ufl
from mpi4py import MPI
mesh = dfx.mesh.create_rectangle(MPI.COMM_WORLD,np.array([[0,0],[1., 1.]]), [1,1], cell_type=dfx.mesh.CellType.quadrilateral)
V = dfx.fem.FunctionSpace(mesh,("CG",1))
v = dfx.fem.Function(V)
v_= ufl.TestFunction(V)
v.vector.array[:] = np.random.random(v.vector.array.size)
avg = dfx.fem.form(ufl.inner(v,ufl.cell_avg(v_))*ufl.dx)
f = dfx.fem.petsc.assemble_vector(avg)
I get the following error message
Traceback (most recent call last):
File "/home/srosenbu/git-packages/fenicsX-constitutive/test/test_b_bar.py", line 16, in <module>
avg = dfx.fem.form(ufl.inner(v,ufl.cell_avg(v_))*ufl.dx)
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/dolfinx/fem/forms.py", line 166, in form
return _create_form(form)
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/dolfinx/fem/forms.py", line 161, in _create_form
return _form(form)
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/dolfinx/fem/forms.py", line 135, in _form
ufcx_form, module, code = jit.ffcx_jit(mesh.comm, form,
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/dolfinx/jit.py", line 56, in mpi_jit
return local_jit(*args, **kwargs)
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/dolfinx/jit.py", line 204, in ffcx_jit
r = ffcx.codegeneration.jit.compile_forms([ufl_object], parameters=p_ffcx, **p_jit)
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/ffcx/codegeneration/jit.py", line 168, in compile_forms
impl = _compile_objects(decl, forms, form_names, module_name, p, cache_dir,
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/ffcx/codegeneration/jit.py", line 232, in _compile_objects
_, code_body = ffcx.compiler.compile_ufl_objects(ufl_objects, prefix=module_name, parameters=parameters)
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/ffcx/compiler.py", line 102, in compile_ufl_objects
ir = compute_ir(analysis, object_names, prefix, parameters, visualise)
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/ffcx/ir/representation.py", line 198, in compute_ir
irs = [
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/ffcx/ir/representation.py", line 199, in <listcomp>
_compute_integral_ir(fd, i, analysis.element_numbers, integral_names, finite_element_names,
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/ffcx/ir/representation.py", line 480, in _compute_integral_ir
integral_ir = compute_integral_ir(itg_data.domain.ufl_cell(), itg_data.integral_type,
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/ffcx/ir/integral.py", line 65, in compute_integral_ir
expression = balance_modifiers(expression)
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/ufl/algorithms/balancing.py", line 76, in balance_modifiers
return map_expr_dag(mf, expr)
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/ufl/corealg/map_dag.py", line 36, in map_expr_dag
result, = map_expr_dags(function, [expression], compress=compress,
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/ufl/corealg/map_dag.py", line 99, in map_expr_dags
r = handlers[v._ufl_typecode_](v, *[vcache[u] for u in v.ufl_operands])
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/ufl/algorithms/balancing.py", line 63, in _modifier
return balance_modified_terminal(expr)
File "/home/srosenbu/mambaforge/envs/dolfinx/lib/python3.10/site-packages/ufl/algorithms/balancing.py", line 31, in balance_modified_terminal
assert expr._ufl_is_terminal_modifier_
AssertionError
I am using dolfinx 0.5.0 which was installed from conda-forge.
I have already looked into the ufl-documentation, but I am not sure what exactly a terminal modifier is and why this would matter.