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

How to assemble a trilinear form?

+3 votes

For model reduction purposes I want to assemble the trilinear form
$$(\nabla \cdot(u*v), w)$$
that is associated with the convection term in the Navier-Stokes equations. Eventually, I want to have a matrix in $\mathbb R^{n,n^2}$ that I can multply $u \otimes u$ with to get the convection term.

For a start, I simply want to assemble the form $(u*v, w)$, with u and v from the same trial space and w from the test space:

import dolfin
from dolfin import dx

N = 10
mesh = dolfin.UnitSquareMesh(N, N)

V = dolfin.FunctionSpace(mesh, 'CG', 2)
U = dolfin.FunctionSpace(mesh, 'CG', 2)

v = dolfin.TestFunction(V)
u = dolfin.TestFunction(U)

w = dolfin.TrialFunction(V)

nform = dolfin.assemble(u*v*w*dx)

However, this direct approach fails, with

UFLException: Found different Arguments with same counts.
Did you combine test or trial functions from different spaces?

Following Jan's answer to this question, I suspect I have to resort to the argument class in UFL. However, I have difficulties to understand this class. So my questions are:

  1. What are the possibilities to assemble this trilinear form?
  2. How to use the arguments class?
asked Mar 31, 2014 by Jan FEniCS User (8,290 points)

2 Answers

+1 vote
 
Best answer

Eventually, I did it 'manually'. I wrote a loop over the basis functions in U and assembled the form for every fixed basis function.

Then, after resorting the arrays, I tiled the arrays into one very large field.

The code is here:

https://github.com/highlando/dolfin_navier_scipy/blob/master/dolfin_to_sparrays.py#L30

answered Jun 21, 2014 by Jan FEniCS User (8,290 points)
edited Feb 13, 2015 by Jan
0 votes

Try this:

from dolfin import *

N = 10
mesh = UnitSquareMesh(N, N)

V = FunctionSpace(mesh, 'CG', 2)

v = TestFunction(V)
u = TestFunction(V)

w = TrialFunction(V)

nform  = inner(div(u*v),w)*dx
answered Mar 31, 2014 by sixtysymbols FEniCS User (2,280 points)
edited Mar 31, 2014 by sixtysymbols

Hi, thanks for the answer. However, I get an UFLException, when I try to assemble nform then.

Did you build your functions on the same function space (V)?

In your original code, you had two separate spaces U and V, which also throws an exception for me. When I define the functions on the same space (see my above code), however, no error arises.

Sure, until the line with nform, I don't have any problems. Just

assemble(inner(div(u*v),w)*dx)

throws an exception.

UFLException: Invalid number of indices (1) for tensor expression of rank 0:
Power(Argument(FiniteElement('Lagrange', Domain(Cell('triangle', 2), 'triangle_multiverse', 2, 2), 2, None), -2), IntValue(2, (), (), {}))

...