This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

How to assemble multilinear form

+2 votes

I'm trying to assemble a multilinear form (for no purpose other than understanding better what's happening). From the FEniCS book, I understand that a multilinear form of arity-2 should result in a rank 2 tensor after assembly. So I tried to assemble something trivial:

# (define v1 and v2)
A = assemble(v1 * v2 * dx)

I was not quite sure how assembly depends on v1 and v2 being test functions or trial functions (at this stage, there didn't seem to be any difference), so I opted for test functions.

However, none of the following definitions worked at all:

# First try
V = FunctionSpace(mesh, 'CG', 1)
(v1, v2) = (TestFunction(V), TestFunction(V))
A = assemble(v1 * v2 * dx) # "Invalid expression"

# Second try
V = FunctionSpace(mesh, 'CG', 1)
(v1, v2) = TestFunction(V*V)
A = assemble(v1 * v2 * dx) # "Unable to extract all indices."

# Third try
V = VectorFunctionSpace(mesh, 'CG', 1)
v = TestFunction(V)
(v1, v2) = (v[0], v[1])
A = assemble(v1 * v2 * dx) # "Unable to extract all indices."

Could someone explain to me what's wrong with each of these, and how to do it right?

asked Feb 1, 2014 by Nikolaus Rath FEniCS User (2,100 points)

1 Answer

+1 vote

Your mistakes in comments below

# First try
V = FunctionSpace(mesh, 'CG', 1)
(v1, v2) = (TestFunction(V), TestFunction(V))
A = assemble(v1 * v2 * dx) # "Invalid expression"
# Is nonlinear

# Second try
V = FunctionSpace(mesh, 'CG', 1)
(v1, v2) = TestFunction(V*V)
A = assemble(v1 * v2 * dx) # "Unable to extract all indices."
# What is a multiplication of mixed fuctions?
# Moreover, is nonlinear

# Third try
V = VectorFunctionSpace(mesh, 'CG', 1)
v = TestFunction(V)
(v1, v2) = (v[0], v[1])
A = assemble(v1 * v2 * dx) # "Unable to extract all indices."
# Is nonlinear

Examples of correct bilinear (rank 2 multilinear forms):

# Arbitrary scalar space
V = FunctionSpace(...)

# Let's assemble L^2 inner product
u, v = TrialFunction(V), TestFunction(V)
A = assemble(u*v*dx)

# Or assemble any other form which is linear in both u, v,
# for example H_0^1 inner product
A = assemble(inner(grad(u), grad(v))*dx)
answered Feb 3, 2014 by Jan Blechta FEniCS Expert (51,420 points)
edited Feb 3, 2014 by Jan Blechta

How can u*v*dx be both linear and non-linear, depending on u being a test or trial function? As far as I know, a multilinear form distinguishes only between coefficient functions and argument functions, but it should not matter at all if an argument represents a test function or a trial function in some variational problem.

In FEniCS it holds:

  • trial function is first argument
  • test function is last argument
  • multi-linear form has to be linear in each of its arguments
  • multi-linear form can depend non-linearly on coefficients
  • DOLFIN can assemble forms of rank

    • 0 (no arguments),
    • 1 (has (customarily) test function),
    • 2 (has trial and test function)
...