Hi,
I am considering the simple optimization problem
$0.5 \cdot \| y - y_d \|^2 + \alpha \|u^2\|^2$
such that $-\Delta y = u$ in $\Omega$ and zero Dirchlet boundary conditions. This can be easy solved with the use of the Lagrange-Funktion
from dolfin import *
mesh = UnitSquareMesh(100,100)
U = FunctionSpace(mesh, "CG", 1)
Z = MixedFunctionSpace([U, U, U])
z = Function(Z)
(y, p, u) = split(z)
F = inner(grad(y) , grad(p))*dx - u*p*dx
yd = Expression(...)
J = inner(y-yd, y-yd)*dx + Constant(alpha)*inner(u,u)*dx
bc_y = DirichletBZ(Z.sub(0), 0.0, "on_boundary")
bc_p = DirichletBZ(Z.sub(1), 0.0, "on_boundary")
bcs = [bc_y, bc_p]
L = J + F
kkt = derivative(L, z, TestFunction(Z))
solve(kkt == 0, z, bcs)
plot(y)
plot(u)
interactive()
I now want to add the control constaints $-1 \leq u \leq 1$. According to several threads here I should use PETScSNESSolver. I am not sure how to change the Form of F properly to NonVariationalForm F(u,v):
Second: How do i impose box constraints only to u (as part of z) )
from dolfin import *
mesh = UnitSquareMesh(100,100)
U = FunctionSpace(mesh, "CG", 1)
Z = MixedFunctionSpace([U, U, U])
v = TestFunction(U)
z = Function(Z)
(y, p, u) = split(z)
F = inner(grad(y) , grad(p))*v*dx - u*p*v*dx
yd = Expression(...)
J = inner(y-yd, y-yd)*v*dx + Constant(alpha)*inner(u,u)*v*dx
bc_y = DirichletBZ(Z.sub(0), 0.0, "on_boundary")
bc_p = DirichletBZ(Z.sub(1), 0.0, "on_boundary")
bcs = [bc_y, bc_p]
L = J + F
kkt = derivative(L, z, TestFunction(Z))
d_kkt = derivative(kkt, z, TestFunction(Z))
# How to impose correctly? This is obviously wrong?
constraint_u = Constant(-1)
constraint_l = Constant(1)
umin = interpolate(constraint_l, Z.sub(2))
umax = interpolate(constraint_u, Z.sub(2))
snes_solver_parameters = {"nonlinear_solver": "snes",
"snes_solver": {"linear_solver": "lu",
"maximum_iterations": 20,
"report": True,
"error_on_nonconvergence": False}}
problem = NonlinearVariationalProblem(kkt, u, bc, d_kkt)
problem.set_bounds(umin, umax)
solver = NonlinearVariationalSolver(problem)
solver.parameters.update(snes_solver_parameters)
info(solver.parameters, True)
(iter, converged) = solver.solve()
plot(y)
plot(u)
interactive()
Of course the code above is not working - the definition of umin and umax is wrong:
Error: Unable to create function
Error: Connot be created from subspace. Consider collapsing the function space
How do i have to change the code to make it run? Or: What am i doing wrong.
Best regards