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

assign giving wrong results assigning subfunctions of a mixed FE function

+2 votes

In some circumstances when assign is used to assign the subfunctions of a function in a mixed function space, it gives a completely wrong answer. Here is a very simplified program that shows the problem. Is this a bug in assign, or have I misunderstood something?

from dolfin import *
# create a mixed function space X = X0 x X1
mesh = UnitSquareMesh(1, 1)
X0 = VectorFunctionSpace(mesh, 'BDM', 1)
X1 = FunctionSpace(mesh, 'DG', 0)
X = MixedFunctionSpace([X0, X1])
# create any nonzero functions in X0 and X1
x0 = interpolate(Constant((("1", "2"), ("3", "4"))), X0)
x1 = interpolate(Constant("5"), X1)
# combine into a function in X: x = (x0, x1)
## method 1: use projection, this gives the right answer
y0, y1 = TrialFunctions(X)
z0, z1 = TestFunctions(X)
a = (inner(y0, z0) + inner(y1, z1) )*dx
L = (inner(x0, z0) + inner(x1, z1)  )*dx
xproj = Function(X)
solve(a == L, xproj)
print  "Evaluating projected fn.  Should give 1, 2, 3, 4, 5."
print xproj(.1,.1)
## method 2: use assignment, this gives the wrong answer
xassign = Function(X)
assign(xassign.sub(0), x0)
assign(xassign.sub(1), x1)
print  "Evaluating assigned fn.  Should give 1, 2, 3, 4, 5."
print xassign(.1, .1)

The output is

Solving linear variational problem.
Evaluating projected fn.  Should give 1, 2, 3, 4, 5.
[ 1.  2.  3.  4.  5.]
Evaluating assigned fn.  Should give 1, 2, 3, 4, 5.
[ 1.4  2.  -1.5 -0.5  5. ]

As the example program shows, a way around this is to compute a projection. But it seems like it should not be necessary to solve a linear system just to assign known coefficients.

asked Feb 17, 2014 by dnarnold FEniCS User (2,360 points)

2 Answers

+1 vote
 
Best answer

This should be fixed in the development version of DOLFIN.

answered Mar 2, 2014 by johanhake FEniCS Expert (22,480 points)
selected Mar 2, 2014 by dnarnold
+2 votes

This looks like a bug in the FunctionAssigner class. I'll report the bug on bitbucket.

Here is a temporary workaround in case you don't want to do the project:

dofs = X.sub(0).dofmap().collapse(mesh)[1].values()
xassign.vector()[dofs] = x0.vector()
assign(xassign.sub(1), x1)  # This one works
answered Feb 19, 2014 by mikael-mortensen FEniCS Expert (29,340 points)
edited Feb 19, 2014 by mikael-mortensen
...