Adding expressions with non-matching form arguments () vs ('v_1',)

Hello,
I am new to Fenics and I have a Problem which I tried to solve the last days on my own but I didn’t managed.
I have a very basic example: a Neo-Hook Material Law for the calculation of sigma and I want to implement the momentum balance.
When I define u - the displacement, as a TrialFunction I get the error in the Titel, If I define it as a normal Function it works.
I have read, that you can’t use TrialFunctions for Non-Linear Problems is this also the Problem here?

I want to couple this equation in the next step with another equation and therefore want to use a mixed space which (In my understanding at least) works best if you define the Functions you use there like u,p = TrialFunctions(Name of the Space)
So it would be great if I could use the TrialFunction for the Definition of my Deformation Gradient. Is there a way to do this?
I run Fenics on ubuntu.
Thank you for you help in advanced!

Here is my code:
(the complete error message is at the end)

from future import print_function
from fenics import *

Elasticity parameters

E, nu = 220, 0.45 # E in kPa
mu = Constant(E/(2*(1 + nu)))
lam = Constant(Enu/( (1+nu)(1-2*nu)))
nu = Constant(nu)

Create mesh and define function space

mesh = UnitSquareMesh(16, 16)
V = VectorFunctionSpace(mesh, ‘P’, 2)

Mark boundary subdomians

left = ‘near(x[0], 0)’
bcu = DirichletBC(V, Constant((0, 0)), left)

Define variational problem

u = TrialFunction(V)
d = u.geometric_dimension() # space dimension
v = TestFunction(V)
t = Constant((0, 10))

Define strain and stress

I = Identity(d)
F = I + nabla_grad(u) # Deformation Gradient
C = F.T*F # Right Cauchy-Green tensor
C_inv = inv(C) # Inverse of Right Cauchy-Green tensor
J = det(F)

def sigma(u):
return (1/J)*mu*I -mu*pow(pow(J,2),-nu/(1-2*nu) )*C_inv*F.T

L = inner(sigma(u), nabla_grad(v))*dx - dot(t, v)*ds

Compute solution

u = Function(V)
solve(L == 0, u, bcu)

Plot solution

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

Error Message:

No Jacobian form specified for nonlinear variational problem.
Differentiating residual form F to obtain Jacobian J = F’.
Calling FFC just-in-time (JIT) compiler, this may take some time.
Traceback (most recent call last):
File “/home/johannes/Desktop/Beleg/mechanik_v2_1.py”, line 38, in
solve(L == 0, u, bcu)
File “/usr/lib/python3/dist-packages/dolfin/fem/solving.py”, line 220, in solve
_solve_varproblem(*args, **kwargs)
File “/usr/lib/python3/dist-packages/dolfin/fem/solving.py”, line 261, in _solve_varproblem
form_compiler_parameters=form_compiler_parameters)
File “/usr/lib/python3/dist-packages/dolfin/fem/problem.py”, line 90, in init
F = Form(F, form_compiler_parameters=form_compiler_parameters)
File “/usr/lib/python3/dist-packages/dolfin/fem/form.py”, line 44, in init
mpi_comm=mesh.mpi_comm())
File “/usr/lib/python3/dist-packages/dolfin/jit/jit.py”, line 47, in mpi_jit
return local_jit(*args, **kwargs)
File “/usr/lib/python3/dist-packages/dolfin/jit/jit.py”, line 97, in ffc_jit
return ffc.jit(ufl_form, parameters=p)
File “/usr/lib/python3/dist-packages/ffc/jitcompiler.py”, line 217, in jit
module = jit_build(ufl_object, module_name, parameters)
File “/usr/lib/python3/dist-packages/ffc/jitcompiler.py”, line 133, in jit_build
generate=jit_generate)
File “/usr/lib/python3/dist-packages/dijitso/jit.py”, line 165, in jit
header, source, dependencies = generate(jitable, name, signature, params[“generator”])
File “/usr/lib/python3/dist-packages/ffc/jitcompiler.py”, line 66, in jit_generate
prefix=module_name, parameters=parameters, jit=True)
File “/usr/lib/python3/dist-packages/ffc/compiler.py”, line 143, in compile_form
prefix, parameters, jit)
File “/usr/lib/python3/dist-packages/ffc/compiler.py”, line 185, in compile_ufl_objects
analysis = analyze_ufl_objects(ufl_objects, kind, parameters)
File “/usr/lib/python3/dist-packages/ffc/analysis.py”, line 90, in analyze_ufl_objects
for form in forms)
File “/usr/lib/python3/dist-packages/ffc/analysis.py”, line 90, in
for form in forms)
File “/usr/lib/python3/dist-packages/ffc/analysis.py”, line 174, in _analyze_form
do_apply_restrictions=True)
File “/usr/lib/python3/dist-packages/ufl/algorithms/compute_form_data.py”, line 418, in compute_form_data
check_form_arity(preprocessed_form, self.original_form.arguments(), complex_mode) # Currently testing how fast this is
File “/usr/lib/python3/dist-packages/ufl/algorithms/check_arities.py”, line 177, in check_form_arity
check_integrand_arity(itg.integrand(), arguments, complex_mode)
File “/usr/lib/python3/dist-packages/ufl/algorithms/check_arities.py”, line 159, in check_integrand_arity
arg_tuples = map_expr_dag(rules, expr, compress=False)
File “/usr/lib/python3/dist-packages/ufl/corealg/map_dag.py”, line 37, in map_expr_dag
result, = map_expr_dags(function, [expression], compress=compress)
File “/usr/lib/python3/dist-packages/ufl/corealg/map_dag.py”, line 86, in map_expr_dags
r = handlers[v.ufl_typecode](v, *[vcache[u] for u in v.ufl_operands])
File “/usr/lib/python3/dist-packages/ufl/algorithms/check_arities.py”, line 48, in sum
raise ArityMismatch(“Adding expressions with non-matching form arguments {0} vs {1}.”.format(_afmt(a), _afmt(b)))
ufl.algorithms.check_arities.ArityMismatch: Adding expressions with non-matching form arguments () vs (‘v_1’,).

See here. https://fenicsproject.org/pub/tutorial/sphinx1/._ftut1004.html#a-nonlinear-poisson-equation

For nonlinear problems, you use Function instead of TrialFunction. The TrialFunction comes into play when the Jacobian of the form is created with derivative. (Otherwise, if you must, linearize the nonlinear form yourself and define a linear variational problem using TrialFunction.)

On the other hand, you can simply define the other (linear?) problem you mention in terms of Function instead of TrialFunction. You can obtain a bilinear form with derivative(form, u).
Anyways, I don’t see any reason why you would have to use TrialFunction for a mixed function space.

edit: maybe clearer with an example

from dolfin import *
mesh = UnitSquareMesh(16, 16)
V = FunctionSpace(mesh, 'P', 1)
u = Function(V)
w = TrialFunction(V)
v = TestFunction(V)

# with trial function
a1 = inner(grad(w), grad(v))*dx
# with function
a2 = inner(grad(u), grad(v))*dx
# rhs (for both)
L = Constant(1)*v*dx

bc = DirichletBC(V, Constant(1), 'on_boundary')

# solve trial function problem
u1 = Function(V)
solve(a1 == L, u1, bc)

# solve function problem
J = derivative(a2, u)
solve(J == L, u, bc)
# # or pretend nonlinearity: solve(a2 - L == 0, u, bc)

# compare solutions
u1.vector().axpy(-1, u.vector())
print('error: ', norm(u1.vector(), 'linf'))
2 Likes

Thank you very much.
I thought you kinda had to use a TrialFunction. But if you don’t its fine.
And also thank you for the example!

I recently stumbled across the same error (see Resolution of the wave equation using Runge-Kutta), do you have any suggestions on how to deal with this?