Issue with updating time in mixed space

Hello,

I am solving a time-dependent problem using Mixed element space. However, it seems that my code is not updating the time parameter in mixed space. Can anyone help me with this issue?
My minimal code is attached below:

from dolfin import *
mesh = RectangleMesh(Point(-1,-1),Point(1,1), 4, 4)
CG1 = VectorElement("Lagrange", mesh.ufl_cell(), 2)
CG2 = VectorElement("Lagrange", mesh.ufl_cell(), 2)
element = MixedElement([CG1, CG2])
W = FunctionSpace(mesh, element)
dw = TrialFunction(W)
v = TestFunction(W)
w  = Function(W)
y, d = split(w)
def right(x, on_boundary):
    return abs(x[0] -1) <  DOLFIN_EPS and on_boundary
load = Expression(("x[0]*(1+t)", "x[1]"), t=0, degree=1)
t, deltaT = 0, 1e-2
t += deltaT
load.t=t
BCS = [DirichletBC(W.sub(0), load, right)]
y0 = interpolate(load, W.sub(0).collapse())
d_initial = Constant((0,0)) 
d0 = interpolate(d_initial, W.sub(1).collapse())
assign(w, [y0, d0])
def W(y): 
    F = grad(y)             
    return 0.5*tr(F.T*F) + (det(F)-1)**2 -ln(det(F))                                
Pi = (1-dot(d, d) )*W(y) *dx 
dPi = derivative(Pi, w, v)
ddPi = derivative(dPi, w, dw) 
problem = NonlinearVariationalProblem(dPi, w, bcs= BCS, J= ddPi)
solver = NonlinearVariationalSolver(problem)    
#t, deltaT = 0, 1e-2
#t += deltaT
#load.t=t
solver.solve()

Please note that if I comment lines 14-16, and use lines 30-32 instead, I will get differet initial starting values, which (I think) is because line y0 = interpolate(load, W.sub(0).collapse()) is Not being updated in this case.

What exactly do you mean by “updating the time parameter in mixed space”. What function would you like to update? Why do you get the impression that it does not work?
I believe that you can only update Expressions which then have to be interpolated or projected in-/onto a function space again within each iteration.

Thanks for the reply. By updating the time parameter in mixed space, I mean variable t is not being updated to t += deltaT .
The reason that I get the impression it is not working is that I get different residuals of functions when I use lines 30-32 instead of lines 14-16.

The reason is not the mixed space but your use of updating the expression. When you call

load.t=t

only the Expression load will be updated however not its interpolate y0 nor the function w. Therefore you simply start with a different initial condition. When using lines 14-16 you use the initial condition described by the expression load for t=dt while when you use lines 30-32 you still consider load for t=0 as initial condition. Maybe try running the following code and look at the example:

from dolfin import *
mesh = RectangleMesh(Point(-1,-1),Point(1,1), 4, 4)
CG1 = VectorElement("Lagrange", mesh.ufl_cell(), 2)
CG2 = VectorElement("Lagrange", mesh.ufl_cell(), 2)
element = MixedElement([CG1, CG2])
W = FunctionSpace(mesh, element)
load = Expression(("t", "0"), t=0, degree=1)


t, deltaT = 0, 1
t += deltaT
y0 = Function(W.sub(0).collapse())
print(y0.vector()[1:10])
# since the function is defined after the updated expression it will take the according values in t
print(t)
load.t=t
y0 = interpolate(load, W.sub(0).collapse())
print(y0.vector()[1:10])


# later update of t only effect the expression not the function y0
t += deltaT
print(t)
load.t=t
print(y0.vector()[1:10])

The workaround is to simply redefine y0 as interpolate after lines 30-32.

1 Like

Thanks for the example. In my code, when I write y0 = interpolate(load, W.sub(0).collapse()) before the last line (solver.solve() ), and use lines 30-32, I get: AttributeError: 'function' object has no attribute 'sub' .
Can you please tell me why I am getting this error?

Thanks,

Can you provide the full example with the code? There seems to be something wrong with either calling the moved function somewhere else or the function space.

Thanks. Here is the code:

from dolfin import *
mesh = RectangleMesh(Point(-1,-1),Point(1,1), 4, 4)
CG1 = VectorElement("Lagrange", mesh.ufl_cell(), 2)
CG2 = VectorElement("Lagrange", mesh.ufl_cell(), 2)
element = MixedElement([CG1, CG2])
W = FunctionSpace(mesh, element)
dw = TrialFunction(W)
v = TestFunction(W)
w  = Function(W)
y, d = split(w)
def right(x, on_boundary):
    return abs(x[0] -1) <  DOLFIN_EPS and on_boundary
load = Expression(("x[0]*(1+t)", "x[1]"), t=0, degree=1)
# t, deltaT = 0, 1e-2
# t += deltaT
# load.t=t
BCS = [DirichletBC(W.sub(0), load, right)]
y0 = interpolate(load, W.sub(0).collapse())
d_initial = Constant((0,0)) 
d0 = interpolate(d_initial, W.sub(1).collapse())
assign(w, [y0, d0])
def W(y): 
    F = grad(y)             
    return 0.5*tr(F.T*F) + (det(F)-1)**2 -ln(det(F))                                
Pi = (1-dot(d, d) )*W(y) *dx 
dPi = derivative(Pi, w, v)
ddPi = derivative(dPi, w, dw) 
problem = NonlinearVariationalProblem(dPi, w, bcs= BCS, J= ddPi)
solver = NonlinearVariationalSolver(problem)    
t, deltaT = 0, 1e-2
t += deltaT
load.t=t
y0 = interpolate(load, W.sub(0).collapse())
solver.solve()

Here is the source of the error. You are using W for the energy as well as the function space. Try renaming it to something else.

2 Likes

Thank you so much! @bhaveshshrimali