Updating "Initial" Function Per Time Step Not Working. Wrong Function Space When Assigning New Function

Dolfin version: 2019.1.0
How installed: manual commands from a source repository in terminal
System: Ubuntu 19.10

I am solving the heat equation on the unit square x [0, T] using space-time CGq method. Each subinterval [t_n, t_n+1] there are q coupled equations that need to be solved together to find the spatial coefficient functions. I then update the “initial” solution with the t_n+1 solution calculated prior. Rinse and repeat as necessary. To start I have to create a q dimensional vector element for the solution to the coupled equations, but the “initial” solution is located in a non-vector element space. I am having an issue updating my “initial” condition. When I use the command alpha_n.assign(alpha[-1]) it gives the following error.

RuntimeError: Expected a Function or linear combinations of Functions in the same FunctionSpace

This seems to me that the component function vector spaces are different than the vector spaces that I am using for u_n at the start and when I try to assign the new value it errors out due to the objects not lying in the same vector space.

I update in my code exactly the same as the following MWE. The issue is reproduced in the MWE. I would like a way to extract the information from my vector function, or to change the vector space that I use for my initial function.

#Create mesh.
mesh = UnitSquareMesh(10, 10)

#Number of subspaces in the function space.
num_spaces = 2

P = FiniteElement(‘CG’, triangle, 2)

#Initialize element array used to make the product vector element.
element_array = []

#For loop to create the array of elements that we will use to make our product vector element.
for i in range(num_spaces):
element_array.append( P)

#Create the vector element.
vector_element = MixedElement(element_array)

#Create Vector Function Space
V_mixed = FunctionSpace(mesh, vector_element)

#Create Single Vector Space
V_single = FunctionSpace(mesh, P)

#Create mixed and single functions.
f_mixed = Function(V_mixed)
f_single = Function(V_single)

#Attempt to update single function.
f_single.assign(f_mixed[-1])

The following modification runs without error:

#Attempt to update single function.
#f_single.assign(f_mixed[-1])
f_single.assign(f_mixed.sub(num_spaces-1,deepcopy=True))
1 Like

Thank you! That does indeed work. Is there some documentation you can point me to to explain what precisely is happening and what the commands are? The more I understand, the less stuck I’ll be in the future.

You can take a look at the automatically-generated API documentation here

https://fenicsproject.org/docs/dolfin/latest/python/api.html

although there is not always much in the way of explanation. On the other hand, FEniCS has a big enough user base that I can often just Google relevant terms until I find a helpful example.

So you found an example of where this was done? Could you share that? I’ve found nothing through my Google searching. It’s why I posted this topic after using FEniCS for 6 months. I finally hit a wall.

I can tell you what is happening:

Your original command calls for the component of the function. This can be used for plotting, weak forms etc. However, the function that you get from indexing is still the same function as before, fenics just knows “for which part of it to look”, i.e., it can disregard the other components.

Now calling the command

f_mixed.sub(num_spaces-1,deepcopy=True)

gives you a deepcopy of the function, that actually “throws away” the information about the other components and is therefore living in the same function space as the function you want to assign it to.

1 Like

I get it now. Thanks for teaching me about the way to think about it!