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

assign split functions

+1 vote

Hi,

I have a coupled function U = V*W, using the split function we have:

(u,r) = U.split()

Now I want to assign u and r into two vectors as follows:

vector1 = u.vector()
vector2 = r.vector()

when i use this command I get the following error:

*** Error:   Unable to access vector of degrees of freedom.
*** Reason:  Cannot access a non-const vector from a subfunction.

My fist question is how can we do such an assignment?
And my second question is that after working and changing vector1 & vector2, how can we again assign them into U ?

asked Feb 25, 2016 by babak FEniCS Novice (380 points)

2 Answers

+1 vote

Use FunctionAssigner. The following should work, but is not tested:

u = Function(V)
r = Function(W)
assigner1 = FunctionAssigner([V,W], U.function_space())
assigner2 = FunctionAssigner(U.function_space(), [V,W])

# Assign U to u,v
assigner1.assign([u,v], U)

# Do some work with u,v

# Assign u,v to U
assigner2.assign(U, [u,v])
answered Feb 26, 2016 by Øyvind Evju FEniCS Expert (17,700 points)

We have:

V = FunctionSpace(...)
W = FunctionSpace(...)
U = V * W

my function is:

p = Function(U)

Now I split p as follows:

(e,f) = p.split()

Now I want to change e and f, then assign them back into p. I don't think that it is necessary to build a correspondence between sub-functions V and W and mixed function W, because we already have such a connection. But I think we can do the following:

assign(p, [e,f])

but when I do this I get the following error:

TypeError: expected a list of shared_ptr<Function> (Bad conversion)

How can we do such an assignment?

There is some overhead of the abovementioned solution, but otherwise I don't see why this is not sufficient?

Would you please explain what is the meaning of that TypeError?

I can't reproduce the error. It works for me with 1.6. However, not accessing the vector as above.

0 votes

If you want to keep the approach you described in your question, simply set the 'deepcopy' argument to True when you split() the Function U, that is, you need to do

u, r = U.split(deepcopy=True)

You can then define vector1 and vector2, as you did in the question. If you modify these vectors and want to update U accordingly, you need to do

assign(U.sub(0), vector1)
assign(U.sub(1), vector2)

Hope it helps.

answered May 5, 2016 by BC FEniCS Novice (790 points)
...