Using the Max function in the cost functional

Asked by ahmad ali

Hallo All
I'm trying to solve PDE constrained optimization problem which has an inequality constrained on the state besides the PDE.

I tried to use the penalty method to get rid of this constraint , but it seemed to me I can't use the Max function in the cost functional. because I got a message like " max is not supported by the UFL "

I mean by Max function the one which gives the maximum of the two arguments i.e. max(0,f(x)).

So, is there any function which do exactly the same job as Max and can be used in the cost functional ?

Question information

Language:
English Edit question
Status:
Solved
For:
dolfin-adjoint Edit question
Assignee:
No assignee Edit question
Solved by:
James Maddison
Solved:
Last query:
Last reply:
Revision history for this message
James Maddison (jamesmadd) said :
#1

Can you give a small example? The Max function should work in UFL expressions.

Revision history for this message
Simon Funke (simon-funke) said :
#2

Hi Ahmad,

I came across this issue a few times as well. You can build your own max function in ufl with the conditional kewywork:

def max(x, y):
  x = triangle.x[0]
  ufl.conditional(gt(x, y), x, y)

Hope this helps.

Simon

Revision history for this message
ahmad ali (cfcf1111) said :
#3

Hi Simon
I just copied your given piece of code and added it to mine , but I still get something like " NameError: global name 'ufl' is not defined.

here is the code I'm using
it is mainly a combination of the examples mentioned in the documentation

from dolfin import *
from dolfin_adjoint import *

# Setup
n = 40
mesh = UnitCircleMesh(n)
V = FunctionSpace(mesh, "CG", 1)

u = Function(V,name="State")
m = Function(V, name="Control")
v = TestFunction(V)

# Run the forward model once to create the simulation record
F = (inner(grad(u), grad(v)) - m*v)*dx
bc = DirichletBC(V, 0.0, "on_boundary")
solve(F == 0, u,bc)

#######################
def max(x, y):
  x = triangle.x[0]
  ufl.conditional(gt(x, y), x, y)
#######################

# The functional of interest is the normed difference between desired
# and simulated temperature profile
x = triangle.x
u_desired = (1-x[0]*x[0]-x[1]*x[1])*x[0]#exp(-1/(1-x[0]*x[0])-1/(1-x[1]*x[1]))
J = Functional(( 0.5*inner(u-u_desired, u-u_desired)+0.1*0.5*inner(m,m)+1/(2*9)*inner(max(0,9*(u-1)),max(0,9*(u-1))) )*dx)

# Run the optimisation
reduced_functional = ReducedFunctional(J, InitialConditionParameter(m, value=m))
# Make sure you have scipy >= 0.11 installed
m_opt = minimize(reduced_functional, method = "L-BFGS-B",
                 tol=2e-08, bounds = (-0.2, 0.2), options = {"disp": True})

###############################################
# desire solution
proj_udes = project(u_desired,V)
plot(u_desired, mesh, interactive=True, title="Desired")
# Actual solution
solve(F == 0, u,bc)
plot(u, interactive=True, title="Actual")
# L1 error
proj_error = project(u-u_desired,V)
plot(proj_error, interactive=True, title="L1-Error")
# Optimal forcing
plot(m_opt, interactive=True, title="Control")

Revision history for this message
Simon Funke (simon-funke) said :
#4

Try adding

import ulf

on the top of your program.

2013/8/1 ahmad ali <email address hidden>:
> Question #233315 on dolfin-adjoint changed:
> https://answers.launchpad.net/dolfin-adjoint/+question/233315
>
> Status: Answered => Open
>
> ahmad ali is still having a problem:
> Hi Simon
> I just copied your given piece of code and added it to mine , but I still get something like " NameError: global name 'ufl' is not defined.
>
>
> here is the code I'm using
> it is mainly a combination of the examples mentioned in the documentation
>
>
> from dolfin import *
> from dolfin_adjoint import *
>
> # Setup
> n = 40
> mesh = UnitCircleMesh(n)
> V = FunctionSpace(mesh, "CG", 1)
>
>
> u = Function(V,name="State")
> m = Function(V, name="Control")
> v = TestFunction(V)
>
> # Run the forward model once to create the simulation record
> F = (inner(grad(u), grad(v)) - m*v)*dx
> bc = DirichletBC(V, 0.0, "on_boundary")
> solve(F == 0, u,bc)
>
> #######################
> def max(x, y):
> x = triangle.x[0]
> ufl.conditional(gt(x, y), x, y)
> #######################
>
> # The functional of interest is the normed difference between desired
> # and simulated temperature profile
> x = triangle.x
> u_desired = (1-x[0]*x[0]-x[1]*x[1])*x[0]#exp(-1/(1-x[0]*x[0])-1/(1-x[1]*x[1]))
> J = Functional(( 0.5*inner(u-u_desired, u-u_desired)+0.1*0.5*inner(m,m)+1/(2*9)*inner(max(0,9*(u-1)),max(0,9*(u-1))) )*dx)
>
> # Run the optimisation
> reduced_functional = ReducedFunctional(J, InitialConditionParameter(m, value=m))
> # Make sure you have scipy >= 0.11 installed
> m_opt = minimize(reduced_functional, method = "L-BFGS-B",
> tol=2e-08, bounds = (-0.2, 0.2), options = {"disp": True})
>
>
> ###############################################
> # desire solution
> proj_udes = project(u_desired,V)
> plot(u_desired, mesh, interactive=True, title="Desired")
> # Actual solution
> solve(F == 0, u,bc)
> plot(u, interactive=True, title="Actual")
> # L1 error
> proj_error = project(u-u_desired,V)
> plot(proj_error, interactive=True, title="L1-Error")
> # Optimal forcing
> plot(m_opt, interactive=True, title="Control")
>
> --
> You received this question notification because you are a member of
> libadjoint developers, which is an answer contact for dolfin-adjoint.

--
Simon Wolfgang Funke

Postdoctoral Research Associate
Imperial College London
Applied Modelling and Computation Group
<email address hidden>

Revision history for this message
ahmad ali (cfcf1111) said :
#5

I did as you said , but i got a message ending with

File "/usr/lib/python2.7/dist-packages/ufl/log.py", line 154, in error
    raise self._exception_type(self._format_raw(*message))
ufl.log.UFLException: Invalid type conversion: <type 'NoneType'> can not be converted to any UFL type.
The representation of the object is:
None

Revision history for this message
Best James Maddison (jamesmadd) said :
#6

def max(x, y):
  import ufl
  x = triangle.x[0]
  return ufl.conditional(gt(x, y), x, y)

should work, or you can use the UFL Max function:

J = Functional(( 0.5*inner(u-u_desired, u-u_desired)+0.1*0.5*inner(m,m)+1/(2*9)*inner(Max(0,9*(u-1)),Max(0,9*(u-1))) )*dx)

Revision history for this message
ahmad ali (cfcf1111) said :
#7

Thanks James Maddison, that solved my question.