I would like to solve an optimization problem with multiple inequality constraints and multiple control variables.
However, even with only one inequality constraint and two control variables, I’m running into some errors.
Here is a minimal non-working example. It runs correctly if I do not add the inequality constraint to the minimization problem.

from dolfin import *
from dolfin_adjoint import *
mesh = UnitSquareMesh(16,16)
V = FunctionSpace(mesh, "CG", 2)
# Initial Function (expression not known in practice)
expr_init_0 = Expression("sin(pi*x[0])*cos(pi*x[1])",degree=3)
expr_init_1 = Expression("cos(3*pi*x[0])",degree=3)
u_0 = interpolate(expr_init_0, V)
u_1 = interpolate(expr_init_1,V)
m0 = Control(u_0)
m1 = Control(u_1)
#"Random" functional chosen to test the implementation
J = assemble(u_0**2 *dx) + assemble( u_1**2 *dx)
Jhat = ReducedFunctional(J,[m0,m1])
param = {"acceptable_tol": 1.0e-3, "maximum_iterations": 10}
volume_constraint0 = UFLInequalityConstraint((0.5 - u_0)*dx, m0)
# volume_constraint1 = UFLInequalityConstraint((0.5 - u_1)*dx, m1)
problem = MinimizationProblem(Jhat, bounds=[(-1, 1),(-1, 1)], constraints=volume_constraint0)
# problem = MinimizationProblem(Jhat, bounds=[(-1, 1),(-1, 1)]) # Without any inequality constraint (uncomment to have a working example)
solver = IPOPTSolver(problem, parameters=param)
u_0_opt, u_1_opt = solver.solve() # Solve the optimization

Do you have any suggestions on how to solve this problem?

As far as I am aware, there is a bug/limitation in dolfin-adjoint atm., which restricts problems to only one control. Removing m1 as a control should give you a running (but not the desired) code.

@sebastkm might be able to yield some more updates on this.

I think I have found a workaround which works for specific cases. I combine the two functions that I desire as control variables into one function defined on a Mixed FunctionSpace and use it as the actual control variable.
The previous minimal working example can be updated as follows:

from dolfin import *
from dolfin_adjoint import *
mesh = UnitSquareMesh(16,16)
V0 = FiniteElement("CG", mesh.ufl_cell(), 2)
V1 = FiniteElement("CG", mesh.ufl_cell(), 2)
W = FunctionSpace(mesh, V0*V1) # mixed function space
w = interpolate(Expression(('sin(pi*x[0])*cos(pi*x[1])', 'cos(3*pi*x[0])'), degree=2), W)
u_0, u_1 = split(w)
m01 = Control(w)
# "Random" functional chosen to test the implementation
J = assemble(u_0**2 *dx) + assemble( u_1**2 *dx)
Jhat = ReducedFunctional(J,m01)
param = {"acceptable_tol": 1.0e-3, "maximum_iterations": 10}
volume_constraint0 = UFLInequalityConstraint(-(0.5 - u_0)*dx, m01)
volume_constraint1 = UFLInequalityConstraint(-(0.5 - u_1)*dx, m01)
problem = MinimizationProblem(Jhat, bounds=[(-1, 1)], constraints=[volume_constraint0,volume_constraint1])
solver = IPOPTSolver(problem, parameters=param)
w_opt = solver.solve() # Solve the optimization
u_0_opt, u_1_opt = split(w_opt)

However, this “tinkering” works only for specific cases and may lead to additional computational time.
So if by any chance @sebastkm has some suggestions, I would gladly accept some additional help

There is an example that works, like the one below, using the optimization module with multiple optimization parameters?
reduced_functional = ReducedFunctional(J, [m1, m2, …])
m_opt = minimize(reduced_functional)

@sebastkm , could you indicate if this bug still exists or if it was solved what the solution was.