replay does not consider a Constant referenced by an Expression referenced by the Functional

Bug #1179927 reported by Martin Sandve Alnæs
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
dolfin-adjoint
Confirmed
High
Patrick Farrell

Bug Description

Output from the code below shows no replay of "t":

Solving linear variational problem.
Solving linear variational problem.
Replay at 0 of u:0:0:Forward, ||f_19|| = 0
Replay at 1 of u:1:0:Forward, ||f_22|| = 0
15.5

Here's the code to reproduce:

from dolfin import *
from dolfin_adjoint import *

t = Constant(0.0, name="t")

mesh = UnitCubeMesh(1,1,1)
d = 3
V = VectorFunctionSpace(mesh, "CG", 1)

ut = TrialFunction(V)
v = TestFunction(V)

u = Function(V, name="u")
g = Function(V, name="g")

c = Constant(0.0, name="c")
f = as_vector((c, 0.0, 0.0))
a = dot(ut,v)*dx
L = dot(f,v)*dx

# A timeloop that assigns to t but doesn't use it in the computation of u
t.assign(0.0)
u.interpolate(Expression(("0.0",)*d))
adj_start_timestep(0.0)
for i in range(1,3):
    t.assign(i)
    solve(a == L, u)
    adj_inc_timestep(i, finished=i==2)

# Validates the replay of u only
assert replay_dolfin(forget=False)

def on_replay(var, func, m):
    print "Replay at %s of %s, ||%s|| = %g" % (var.timestep, str(var), func.name(), norm(func))

# A functional that references t through an Expression attribute
z = Expression("1.0 + 1.0*t", t=t)
Jdist = (g**2 + z**2)*dx*dt
Jfunc = Functional(Jdist)
Jred = ReducedFunctional(Jfunc, [ScalarParameter(c)], replay_cb=on_replay)
print Jred([c])

Revision history for this message
Patrick Farrell (pefarrell) wrote :

Yes, the Expressions have the wrong .t's in the UFL forms for the time integration inside the functional.

A hack workaround, for now:

from dolfin import *
from dolfin_adjoint import *

t = Constant(0.0, name="t")

mesh = UnitCubeMesh(1,1,1)
d = 3
V = VectorFunctionSpace(mesh, "CG", 1)
R = FunctionSpace(mesh, "R", 0)

ut = TrialFunction(V)
v = TestFunction(V)

u = Function(V, name="u")
g = Function(V, name="g")

c = Constant(0.0, name="c")
f = as_vector((c, 0.0, 0.0))
a = dot(ut,v)*dx
L = dot(f,v)*dx
solve(inner(ut, v)*dx == inner(u, v)*dx, u) # initial condition annotation

z = Function(R)
rtest = TestFunction(R)
rtrial = TrialFunction(R)
z_expr = Expression("1.0 + 1.0*t", t=t)
za = inner(rtrial, rtest)*dx
zL = inner(z_expr, rtest)*dx
solve(za == zL, z)

# A timeloop that assigns to t but doesn't use it in the computation of u
t.assign(0.0)
u.interpolate(Expression(("0.0",)*d))
adj_start_timestep(0.0)
for i in range(1,3):
    t.assign(i)
    solve(a == L, u)
    solve(za == zL, z)
    print "time == %s, z == %s" % (i, z.vector()[0])
    adj_inc_timestep(i, finished=i==2)

# Validates the replay of u only
assert replay_dolfin(forget=False)

def on_replay(var, func, m):
    print "Replay at %s of %s, ||%s|| = %g" % (var.timestep, str(var), func.name(), norm(func))

adj_html("forward.html", "forward")

# A functional that references t through an Expression attribute
Jdist = (z**2)*dx*dt
Jfunc = Functional(Jdist)
Jred = ReducedFunctional(Jfunc, [ScalarParameter(c)], replay_cb=on_replay)
print Jred([c])

prints 9.0 as expected.

Changed in dolfin-adjoint:
status: New → Confirmed
importance: Undecided → High
assignee: nobody → Patrick Farrell (pefarrell)
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.