Multiple UFLInequalityConstraint with multiple Control variables

Hello everyone,

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?

Thank you for your time.

3 Likes

Hi,

Have you found the solution?
I’m running into a similar problem…

Not yet, but for sure I’ll post the answer here if I manage 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.

1 Like

Thank you for your answer dokken.

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

1 Like

Esteemed,

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.

Dear @thabuis ,

Did you manage to solve the initial problem?

@sebastkm could you help us with this problem?

This requires a bit of changes to make work in general. I’ve started on a possible solution in this branch: GitHub - dolfin-adjoint/pyadjoint at multiple-ufl-ineq

I believe it will work for the example provided in this post, but the changes might break other constraints/optimizers.

With the changes in my branch you pass all the controls to the UFLConstraint, even when it depends only on one of the two controls:

volume_constraint0 = UFLInequalityConstraint((0.5 - u_0)*dx, [m0, m1])
1 Like