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

Interpolate on MixedFunctionSpace

0 votes

Hi all,

This question is somehow related to
http://fenicsproject.org/qa/8556/interpolation-on-mixef-function-space-failled,
but the above Q/A is too problem specific and I can not understand how to use it to solve my problem.

I would like to understand better why the following piece of code does not behave as expected
(I have tried using both FEniCS 1.5 and FEniCS 1.6).

mesh = dl.UnitSquareMesh(10,10)
V1 = dl.VectorFunctionSpace(mesh, "CG", 2)
V2 = dl.FunctionSpace(mesh, "CG", 1)
V3 = dl.FunctionSpace(mesh, "CG", 1)
V = dl.MixedFunctionSpace([V1,V2,V3])

f1 = dl.Expression( ("A + B*x[1]*(1-x[1])", "0."), A=1., B=1.)
f2 = dl.Expression( "A*x[0]", A=1.)
f3 = dl.Expression( "A", A = -3.)

state = dl.Function(V)
state.sub(0,deepcopy=False).assign( dl.interpolate(f1, V1))
state.sub(1,deepcopy=False).assign( dl.interpolate(f2, V2))
state.sub(2,deepcopy=False).assign( dl.interpolate(f3, V3))

print "|| state ||^2_L^(2) = ", dl.assemble( dl.inner(state, state)*dl.dx)

dl.plot(state.sub(0))
dl.plot(state.sub(1)) 
dl.plot(state.sub(2))

I would expect this code to initialize each component of the state to the functions f1,f2,f3.
However the output of the code is

|| state ||^2_L^(2) = 0.0

and the three plots are identically 0.

What I am missing? This seems that sub() command creates a copy instead of a view of the underlying data.

Could you please suggest some workaround? Please note that the expressions for f1,f2,f3 are actually more complicated, and they MUST use the additional parameters A and B.

Thank you in advance!

Umbe

asked Dec 17, 2015 by umberto FEniCS User (6,440 points)
edited Dec 17, 2015 by umberto

I have also tried out a similar technique, but I am getting the same result:

state = dl.Function(V)
s1, s2, s3 = state.split(deepcopy=False)
s1.assign(dl.interpolate(f1,V1))
s2.assign(dl.interpolate(f2,V2))
s3.assign(dl.interpolate(f3,V3))

print "|| (s1,s2,s3) ||^2_L^(2)  = ", dl.assemble( (dl.inner(s1,s1) + s2*s2 + s3*s3)*dl.dx)
print "|| state ||^2_L^(2) = ", dl.assemble( dl.inner(state, state)*dl.dx)

Output:

|| (s1,s2,s3) ||^2_L^(2) = 10.7
|| state ||^2_L^(2) = 0.0

1 Answer

0 votes
 
Best answer

Hi, consider using FunctionAssigner

import dolfin as dl

mesh = dl.UnitSquareMesh(10,10)
V1 = dl.VectorFunctionSpace(mesh, "CG", 2)
V2 = dl.FunctionSpace(mesh, "CG", 1)
V3 = dl.FunctionSpace(mesh, "CG", 1)
V = dl.MixedFunctionSpace([V1,V2,V3])

f1 = dl.Expression( ("A + B*x[1]*(1-x[1])", "0."), A=1., B=1.)
f2 = dl.Expression( "A*x[0]", A=1.)
f3 = dl.Expression( "A", A = -3.)

F1, F2, F3 = [dl.interpolate(fi, Vi) for fi, Vi in zip((f1, f2, f3), (V1, V2, V3))]

assigner = dl.FunctionAssigner(V, [V1, V2, V3])
state = dl.Function(V)
assigner.assign(state, [F1, F2, F3])

print "|| state ||^2_L^(2) = ", dl.assemble( dl.inner(state, state)*dl.dx)

dl.plot(state.sub(0))
dl.plot(state.sub(1)) 
dl.plot(state.sub(2))

dl.interactive()
answered Dec 18, 2015 by MiroK FEniCS Expert (80,920 points)
selected Dec 18, 2015 by umberto

Hi MiroK,

Thank you very much for pointing out the FunctionAssigner class.
It worked perfectly and it is also extremely clean.

However could you explain why does

state.sub(0,deepcopy=False).assign( dl.interpolate(f1, V1))

modify a temporary data, instead of the data in the state function?

Thanks,

Umberto

...