firedrakeproject / firedrake

Firedrake is an automated system for the portable solution of partial differential equations using the finite element method (FEM)
https://firedrakeproject.org
Other
498 stars 157 forks source link

Errors with firedrake.vector.Vector methods and mixed elements #1276

Open jrmaddison opened 6 years ago

jrmaddison commented 6 years ago

Attempting to update Vectors directly leads to errors when mixed elements are used. For example:

from firedrake import *

mesh = UnitIntervalMesh(10)
element = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
space = FunctionSpace(mesh, element * element)

x = Function(space, name = "x")
y = Function(space, name = "y")

x.vector()[:] = y.vector()
x.vector().axpy(1.0, y.vector())

Either the assignment or the axpy leads to an error, e.g.

Traceback (most recent call last):
  File "firedrake_vector.py", line 14, in <module>
    x.vector()[:] = y.vector()
  File "[...]/firedrake/vector.py", line 217, in __setitem__
    self.dat.data[idx] = value
TypeError: 'tuple' object does not support item assignment
miklos1 commented 6 years ago

This is a mixed space, a mixed space is a bag of function spaces, I suppose that's why you have tuples. Observe what x.vector(), x.vector().dat, and x.vector().dat.data.

I guess what you want to do is: x.assign(y).

wence- commented 6 years ago

It is an ongoing issue that the vector api is not compatible with dolfin.

miklos1 commented 6 years ago

Can't we just allocate mixed Dats as a continuous array, and then slice and reshape sections for individual Dats?

wence- commented 6 years ago

"Just" is a stretch, but something like that could be done. Or, given that I think the vector API operates on assembled objects, one could just expose the Vec objects.

jrmaddison commented 6 years ago

The assign method would probably suffice, but there are use cases where it is desirable to modify the vector directly -- the axpy (now corrected) is probably a better example.

wence- commented 6 years ago

FWIW, Function.assign handles arbitrary (pointwise, nonlinear even) combinations of fields. So you can write:

x.assign(x + alpha*y)

if you like. I realise this doesn't help for compatibility purposes.