replay does not consider a Constant referenced by an Expression referenced by the Functional
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 = VectorFunctionS
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(
adj_start_
for i in range(1,3):
t.assign(i)
solve(a == L, u)
adj_
# Validates the replay of u only
assert replay_
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 = ReducedFunction
print Jred([c])
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) pace(mesh, "CG", 1)
d = 3
V = VectorFunctionS
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 Expression( ("0.0", )*d)) timestep( 0.0) inc_timestep( i, finished=i==2)
t.assign(0.0)
u.interpolate(
adj_start_
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_
# Validates the replay of u only dolfin( forget= False)
assert replay_
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 al(Jfunc, [ScalarParamete r(c)], replay_ cb=on_replay)
Jdist = (z**2)*dx*dt
Jfunc = Functional(Jdist)
Jred = ReducedFunction
print Jred([c])
prints 9.0 as expected.