I am interested in manipulating the source term of an ODE such that the state reaches a specified value at a specified time. For instance, in a minimal example, we would like to manipulate the in_weight function so that the state v is as close to 5 as possible at time point 6 (together with a norm regularization term):
J = (v(6)-5)**2*dx + 0.001*in_weight**2*dx
However, this gives me an error:
“UFLException: This integral is missing an integration domain.”
The error is thrown on that line.
I can optimize the source such that the ODE attains as close to that value as possible over the whole interval without issue:
J = (v-5)**2*dx + 0.001*in_weight**2*dx
The above line works fine.
I anticipate that the problem is that v(6) resolves to a floating point number, and the automatic adjoint chain is broken because there is no reference to the variable v. I do not know how to resolve this.
Here is a python script giving the error for a simple state equation:
from dolfin import * from dolfin_adjoint import * import numpy as np import math import time import moola def bd_func(shift): def boundary(x): return x - shift < DOLFIN_EPS return boundary V0 = Constant(0.0) # Set up function space mesh = IntervalMesh(1000, 0, 2*math.pi) W = FunctionSpace(mesh,'CG',1) bc = DirichletBC(W, V0, bd_func(0.0)) v = Function(W) u = TestFunction(W) in_weight = interpolate(Expression('0.0', degree=2), W) weak_form = v.dx(0)*u*dx -v*u*dx - in_weight*u*dx Jac = derivative(weak_form, v, TrialFunction(W)) solve(weak_form==0,v, J=Jac,bcs=bc) # Optimization at t = 6 (does not work) J = (v(6)-5)**2*dx + 0.001*in_weight**2*dx # Optimization over the whole interval (does work) J = (v-5)**2*dx + 0.001*in_weight**2*dx J=assemble(J) rf = ReducedFunctional(J, Control(in_weight)) problem = MoolaOptimizationProblem(rf) f_moola = moola.DolfinPrimalVector(in_weight) solver = moola.BFGS(problem, f_moola) sol = solver.solve()