Assignment of subfunctions fails: "Expects only linear combinations of Functions in the same FunctionSpaces."

Issue #454 new
Patrick Farrell created an issue

Consider the following demo code:

from dolfin import *

mesh = UnitSquareMesh(2, 2)
V = FunctionSpace(mesh, "CG", 1)
Z = MixedFunctionSpace([V, V])

z1 = interpolate(Constant((1, 1)), Z)
z2 = interpolate(Constant((2, 2)), Z)

v1 = z1.split(deepcopy=True)[0]
v2 = z2.split(deepcopy=True)[0]

v = Function(V)
v.assign(v1 + v2)
This fails with
[pef@aislinn:/tmp]$ python demo.py 
Traceback (most recent call last):
  File "demo.py", line 14, in <module>
    v.assign(v1 + v2)
  File "/home/pef/local/fenics-dev-20141212/src/dolfin/local.master/lib/python2.7/site-packages/dolfin/functions/function.py", line 391, in assign
    multi_index)
  File "/home/pef/local/fenics-dev-20141212/src/dolfin/local.master/lib/python2.7/site-packages/dolfin/functions/function.py", line 165, in _check_and_contract_linear_comb
    _assign_error()
  File "/home/pef/local/fenics-dev-20141212/src/dolfin/local.master/lib/python2.7/site-packages/dolfin/functions/function.py", line 40, in _assign_error
    "Expects only linear combinations of Functions in "\
  File "/home/pef/local/fenics-dev-20141212/src/dolfin/local.master/lib/python2.7/site-packages/dolfin/cpp/common.py", line 2324, in dolfin_error
    return _common.dolfin_error(*args)
RuntimeError: 

*** -------------------------------------------------------------------------
*** DOLFIN encountered an error. If you are not able to resolve this issue
*** using the information listed below, you can ask for help at
***
***     fenics@fenicsproject.org
***
*** Remember to include the error message listed below and, if possible,
*** include a *minimal* running example to reproduce the error.
***
*** -------------------------------------------------------------------------
*** Error:   Unable to assign function.
*** Reason:  Expects only linear combinations of Functions in the same FunctionSpaces.
*** Where:   This error was encountered inside function.py.
*** Process: unknown
*** 
*** DOLFIN version: 1.4.0+
*** Git changeset:  7ad843e6ecb9faa7ba97ee3b8aed56b5690a7244
*** -------------------------------------------------------------------------

Comments (8)

  1. Johan Hake

    This is caused by:

    v1 in V
    

    returning False, which in turn is caused by FunctionSpace::operator==(const FunctionSpace&) uses pointer comparisons of the element, mesh and dofmap. In this case v1 and v2 have reconstructed dofmaps and are therefore evaluated as not the same as V.

    Not sure how to properly resolve this.

  2. Prof Garth Wells

    When making a deep copy, one would need to be able to pass the function space.

    In reported code, there is no guarantee that the DofMap for v1 and v2 are same. For example, the user could have changed the dof ordering method between computing v1 and v2.

  3. Matthias Liertzer

    Note, that you can work around this bug using (see also #405)

    v1, v2 = Function(V), Function(V)
    assign(v1, z1.sub(0))
    assign(v2, z2.sub(0))
    

    When looking into the bug mentioned above, it suprised me that the dofmap is always reconstructed when using the deepcopy option. Since I'm curious: Is there a reason for not simply storing references to the original subspaces and reusing them in the case of the split operator?

  4. Prof Garth Wells

    @mliertzer Caching is generally bad; it eats memory (hidden from user), makes it hard to modify a dofmap without invalidating other objects and can lead to unexpected behaviour. It's better to be explicit.

    Maybe we could add an interface to do something like

    v1 = z1.split(deepcopy=True)[0]
    v2 = z2.split(v1.function_space().dofmap())[0]
    

    It would require more thought to check that it's viable.

  5. Log in to comment