Is it possible to use box constrained Krylov solvers in FEniCS project?
Can I put a non-negative restriction in z.vector() of the code below?
from dolfin import *
parameters["linear_algebra_backend"] = "PETSc"
n = 100
mesh = UnitSquareMesh(n, n)
U = FunctionSpace(mesh, "CG", 1)
V = FunctionSpace(mesh, "CG", 1)
Z = MixedFunctionSpace([U, V])
z = Function(Z)
(u, v) = split(z)
#variational problem
g = Expression("-10.0 * x[0] * x[0] * sin(25 * x[0])")
l = g * v * ds
F = inner(grad(u), grad(v))*dx - l
#functional
J = inner(u, u) * dx
# J = u * dx # Is it possible to put non-negative constrains on u.vector() ?
#optimaly conditions
L = J + F # What about J = u * dx and subject to u.vector() >= 0 ?
kkt = derivative(L, z, TestFunction(Z))
#system assembler (without boudary conditions)
bcs = []
kkt_lin = replace(kkt, {z: TrialFunction(Z)})
kkt_lhs, kkt_rhs = assemble_system(lhs(kkt_lin), rhs(kkt_lin), bcs)
#Krylov solver
solver = KrylovSolver(kkt_lhs, "tfqmr", "icc")
solver.parameters["absolute_tolerance"] = 1e-6
solver.parameters["relative_tolerance"] = 1e-4
solver.parameters["maximum_iterations"] = 1000
solver.parameters["monitor_convergence"] = True
#vector that spans the null space
z = Function(Z)
null_vec = Vector(z.vector())
Z.dofmap().set(null_vec, 1.0)
null_vec *= 1.0/null_vec.norm("l2")
null_space = VectorSpaceBasis([null_vec])
solver.set_nullspace(null_space)
null_space.orthogonalize(kkt_rhs);
#solve
solver.solve(z.vector(), kkt_rhs) # Can we do something like
# solver.solve(z.vector(), kkt_rhs, z.vector() >= 0.0) ?
#plot
(u, lmbd) = split(z)
plot(u, title='u')
interactive()