# Integrating vector fields

**URL:** <https://fenicsproject.discourse.group/t/integrating-vector-fields/246>\
**Category:** variational formulation\
**Created:** [February 20, 2019, 11:30am UTC](https://fenicsproject.discourse.group/t/integrating-vector-fields/246 "2019-02-20T11:30:27Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![freya](https://avatars.discourse-cdn.com/v4/letter/f/a9a28c/32.png) [@freya](https://fenicsproject.discourse.group/u/freya)\
**Post date:** [February 20, 2019, 11:30am UTC](https://fenicsproject.discourse.group/t/integrating-vector-fields/246/1 "2019-02-20T11:30:27Z")

</div>

I would like to integrate vector fields over a given domain. The docs of the assemble  
method seem to suggest the following:

```
from dolfin import *

mesh = UnitSquareMesh(32, 32)
V = VectorFunctionSpace(mesh, "Lagrange", 1)
f = Function(V)

F = PETScVector()                         
assemble(f*dx, tensor = F)

```

However, this returns an error message:  
UFLException: Can only integrate scalar expressions. The integrand is a tensor expression with value shape (2,) and free indices with labels ().

What is the problem here?

---

<div class="post-metadata">

**Author:** ![Leo](https://avatars.discourse-cdn.com/v4/letter/l/c2a13f/32.png) [@Leo](https://fenicsproject.discourse.group/u/Leo)\
**Post date:** [February 20, 2019, 6:11pm UTC](https://fenicsproject.discourse.group/t/integrating-vector-fields/246/2 "2019-02-20T18:11:13Z")

</div>

In this example you can not directly multiply f by dx as f has been defined on a vectorial function space. You may want to incorporate an inner product by defining a test function. Then you will have a scalar variable as an integrand:

```
from dolfin import *
mesh = UnitSquareMesh(32, 32)
V = VectorFunctionSpace(mesh, "Lagrange", 1)
f = Function(V)
v = TestFunction(V)
F = PETScVector()
assemble(inner(f,v)*dx, tensor = F)
```

---

<div class="post-metadata">

**Author:** ![freya](https://avatars.discourse-cdn.com/v4/letter/f/a9a28c/32.png) [@freya](https://fenicsproject.discourse.group/u/freya)\
**Post date:** [February 21, 2019, 9:37am UTC](https://fenicsproject.discourse.group/t/integrating-vector-fields/246/3 "2019-02-21T09:37:58Z")

</div>

Thank you! However, this does not seem to be doing what I want to achieve. The result should contain two real numbers, namely the integrals of each component of the vector field. That is,

```
from dolfin import *
mesh = UnitSquareMesh(32, 32)
V = VectorFunctionSpace(mesh, "Lagrange", 1)
f = Constant((0,1))
f = project(f, V)
v = TestFunction(V)
F = PETScVector()
assemble(inner(f,v)*dx, tensor = F)

```

should return the vector (0,1), but this is not the case.

---

<div class="post-metadata">

**Author:** ![kamensky](https://avatars.discourse-cdn.com/v4/letter/k/e95f7d/32.png) [@kamensky](https://fenicsproject.discourse.group/u/kamensky)\
**Post date:** [February 21, 2019, 9:50am UTC](https://fenicsproject.discourse.group/t/integrating-vector-fields/246/4 "2019-02-21T09:50:39Z")

</div>

Does it work for your purposes to obtain the components as a Python tuple? That can be done by calling assemble for each component of `f` as follows:

```auto
from dolfin import *
mesh = UnitSquareMesh(32, 32)
V = VectorFunctionSpace(mesh, "Lagrange", 1)
f = Function(V)
f.interpolate(Constant((0,1)))
v = (assemble(f[0]*dx),assemble(f[1]*dx))
print(v)

```

---

<div class="post-metadata">

**Author:** ![freya](https://avatars.discourse-cdn.com/v4/letter/f/a9a28c/32.png) [@freya](https://fenicsproject.discourse.group/u/freya)\
**Post date:** [February 21, 2019, 9:56am UTC](https://fenicsproject.discourse.group/t/integrating-vector-fields/246/5 "2019-02-21T09:56:13Z")

</div>

Yes, this would be a workaround. However, this can become quite tedious for higher order tensors. I thought that the tensor keyword of the assemble function was meant for this. Is this not correct?

---

<div class="post-metadata">

**Author:** ![kamensky](https://avatars.discourse-cdn.com/v4/letter/k/e95f7d/32.png) [@kamensky](https://fenicsproject.discourse.group/u/kamensky)\
**Post date:** [February 21, 2019, 10:19am UTC](https://fenicsproject.discourse.group/t/integrating-vector-fields/246/6 "2019-02-21T10:19:03Z")

</div>

The term “tensor” in the context of the `assemble()` function refers to tensors defined on finite element function spaces (e.g., the right-hand-side vector or left-hand-side matrix from the linear system that you would solve) rather than the typical usage in mechanics, referring to tensors defined on the tangent space to your PDE domain (e.g., velocity, stress, etc.). The rank of tensor you get depends on how many trial/test functions are in the form you are assembling (so you get a scalar if there are no test/trial functions, a vector if there is test function, and a matrix if there is a test and a trial function).

---

<div class="post-metadata">

**Author:** ![freya](https://avatars.discourse-cdn.com/v4/letter/f/a9a28c/32.png) [@freya](https://fenicsproject.discourse.group/u/freya)\
**Post date:** [February 21, 2019, 10:22am UTC](https://fenicsproject.discourse.group/t/integrating-vector-fields/246/7 "2019-02-21T10:22:41Z")

</div>

Thank you for clarifying this!

---

<div class="post-metadata">

**Author:** ![mmorandini](https://avatars.discourse-cdn.com/v4/letter/m/eb8c5e/32.png) [@mmorandini](https://fenicsproject.discourse.group/u/mmorandini)\
**Post date:** [February 27, 2019, 8:57am UTC](https://fenicsproject.discourse.group/t/integrating-vector-fields/246/8 "2019-02-27T08:57:18Z")

</div>

You nee to use a “Real” element (i.e. Lagrange multiplier, defined over the whole mesh) to build your test functions:

```auto
from dolfin import *
mesh = UnitSquareMesh(32, 32)
V = VectorFunctionSpace(mesh, "Lagrange", 1)
VR = VectorFunctionSpace(mesh, "R", 0)
f = Constant((0,1))
f = project(f, V)
v = TestFunction(VR)
F = PETScVector()
assemble(inner(f,v)*dx, tensor = F)
print(F[:])

```
