# Using the Max function in the cost functional

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:
Assignee:
No assignee Edit question
Solved by:
Solved:
Last query:
 Revision history for this message James Maddison (jamesmadd) said on 2013-07-31: #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 on 2013-07-31: #2

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 on 2013-08-01: #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 *

# 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
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 on 2013-08-01: #4

import ulf

on the top of your program.

> Question #233315 on dolfin-adjoint changed:
>
>
> 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 *
>
> # 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
> 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

--
Simon Wolfgang Funke

Postdoctoral Research Associate
Imperial College London
Applied Modelling and Computation Group

 Revision history for this message ahmad ali (cfcf1111) said on 2013-08-02: #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 James Maddison (jamesmadd) said on 2013-08-02: #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 on 2013-08-03: #7

Thanks James Maddison, that solved my question.