calling ``vector().set_local()`` on a Function to be used as an upper or lower bound breaks the code.

Issue #92 new
Evan Cummings created an issue

Hi there,

I need to specify optimization bounds per vertex, so I create a two Functions, one for the upper bound and one for the lower bound, iterate through the dofs, and change the bound appropriately.

Calling ::dolfin_adjoint.Function.vector().set_local() on the bounds breaks the optimization. I'm using dolfin 2017.2.0 and dolfin_adjoint 2017.2.0.

To illustrate the problem I'm experiencing, here is minimal code:

from dolfin import *
from dolfin_adjoint import *

set_log_level(ERROR)


# Create mesh
nx = 9
mesh = UnitSquareMesh(nx, nx)

# Define function space
V = FunctionSpace(mesh, "CG", 1)

def forward(f):
    """
    forward model
    """
    u = Function(V, name='State')
    v = TestFunction(V)
    F = inner(grad(u), grad(v)) * dx - f * v *dx
    bc = DirichletBC(V, 0.0, "on_boundary")
    solve(F == 0, u, bc)
    return u

f = Function(V)
f.vector()[:] = 10.0

# run forward model once
u = forward(f)

# define target functional
J = Functional(-inner(u, u) * dx)

# create ReducedFunctional object
rf = ReducedFunctional(J, Control(f))

# form bounds :
upper             = Function(V)
lower             = Function(V)
upper.vector()[:] = 100.0
lower.vector()[:] = 0.0

upper_v = upper.vector().get_local()
lower_v = lower.vector().get_local()

# FIXME: comment this out to get working optimization :
upper.vector().set_local(upper_v)
upper.vector().apply('insert')
lower.vector().set_local(upper_v)
lower.vector().apply('insert')

method = None#'ipopt'

if method == 'ipopt':
  parameters = {"tol"                : 1e-8,
                "acceptable_tol"     : 1e-6,
                "maximum_iterations" : 10,
                "print_level"        : 5,
                "linear_solver"      : "ma97"}
  problem = MinimizationProblem(rf, bounds = (lower,upper))
  solver  = IPOPTSolver(problem, parameters=parameters)
  f_opt   = solver.solve()

else:
  f_opt = minimize(rf, bounds=(lower, upper), tol=1.0e-10)

print f_opt.vector().min(), f_opt.vector().max()

adj_reset()

which produces the output:

RUNNING THE L-BFGS-B CODE

           * * *

Machine precision = 2.220D-16
 N =          100     M =           10
 The initial X is infeasible.  Restart with its projection.

At X0       100 variables are exactly at the bounds

At iterate    0    f= -1.59878D+01    |proj g|=  0.00000D+00

           * * *

Tit   = total number of iterations
Tnf   = total number of function evaluations
Tnint = total number of segments explored during Cauchy searches
Skip  = number of BFGS updates skipped
Nact  = number of active bounds at final generalized Cauchy point
Projg = norm of the final projected gradient
F     = final function value

           * * *

   N    Tit     Tnf  Tnint  Skip  Nact     Projg        F
  100      0      1      0     0     0   0.000D+00  -1.599D+01
  F =  -15.987807497724067     

CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL            

 Cauchy                time 0.000E+00 seconds.
 Subspace minimization time 0.000E+00 seconds.
 Line search           time 0.000E+00 seconds.

 Total User time 0.000E+00 seconds.

100.0 100.0

Commenting the FIXME section out produces:

RUNNING THE L-BFGS-B CODE

           * * *

Machine precision = 2.220D-16
 N =          100     M =           10

At X0         0 variables are exactly at the bounds

At iterate    0    f= -1.59878D-01    |proj g|=  9.04155D-04

At iterate    1    f= -1.59896D-01    |proj g|=  9.04208D-04
  ys=-1.049E-09  -gs= 1.825E-05 BFGS update SKIPPED

At iterate    2    f= -7.17258D+00    |proj g|=  6.15390D-03
  ys=-1.039E+01  -gs= 1.816E+00 BFGS update SKIPPED

At iterate    3    f= -7.18906D+00    |proj g|=  5.44786D-03
  ys=-1.891E-05  -gs= 1.647E-02 BFGS update SKIPPED

At iterate    4    f= -8.47734D+00    |proj g|=  5.87717D-03
  ys=-1.063E-01  -gs= 1.235E+00 BFGS update SKIPPED

At iterate    5    f= -8.52797D+00    |proj g|=  5.26093D-03
  ys=-1.516E-04  -gs= 5.056E-02 BFGS update SKIPPED

At iterate    6    f= -9.48446D+00    |proj g|=  5.43945D-03
  ys=-5.149E-02  -gs= 9.307E-01 BFGS update SKIPPED

At iterate    7    f= -9.62768D+00    |proj g|=  4.70543D-03
  ys=-1.092E-03  -gs= 1.427E-01 BFGS update SKIPPED

At iterate    8    f= -1.09256D+01    |proj g|=  4.95639D-03
  ys=-8.367E-02  -gs= 1.256E+00 BFGS update SKIPPED

At iterate    9    f= -1.10076D+01    |proj g|=  4.49719D-03
  ys=-3.148E-04  -gs= 8.181E-02 BFGS update SKIPPED

At iterate   10    f= -1.16506D+01    |proj g|=  4.46099D-03
  ys=-1.898E-02  -gs= 6.335E-01 BFGS update SKIPPED

At iterate   11    f= -1.18359D+01    |proj g|=  3.54869D-03
  ys=-1.554E-03  -gs= 1.845E-01 BFGS update SKIPPED

At iterate   12    f= -1.28820D+01    |proj g|=  3.45171D-03
  ys=-4.731E-02  -gs= 1.022E+00 BFGS update SKIPPED

At iterate   13    f= -1.32101D+01    |proj g|=  2.97406D-03
  ys=-4.428E-03  -gs= 3.259E-01 BFGS update SKIPPED

At iterate   14    f= -1.39678D+01    |proj g|=  2.99354D-03
  ys=-2.247E-02  -gs= 7.465E-01 BFGS update SKIPPED

At iterate   15    f= -1.40594D+01    |proj g|=  2.78691D-03
  ys=-3.221E-04  -gs= 9.137E-02 BFGS update SKIPPED

At iterate   16    f= -1.42940D+01    |proj g|=  2.61152D-03
  ys=-2.148E-03  -gs= 2.335E-01 BFGS update SKIPPED

At iterate   17    f= -1.44692D+01    |proj g|=  2.20336D-03
  ys=-1.247E-03  -gs= 1.746E-01 BFGS update SKIPPED

At iterate   18    f= -1.47621D+01    |proj g|=  1.91682D-03
  ys=-3.587E-03  -gs= 2.911E-01 BFGS update SKIPPED

At iterate   19    f= -1.49303D+01    |proj g|=  1.31439D-03
  ys=-1.334E-03  -gs= 1.676E-01 BFGS update SKIPPED

At iterate   20    f= -1.51642D+01    |proj g|=  9.48153D-04
  ys=-2.288E-03  -gs= 2.327E-01 BFGS update SKIPPED

At iterate   21    f= -1.53658D+01    |proj g|=  5.53753D-04
  ys=-1.648E-03  -gs= 2.007E-01 BFGS update SKIPPED

At iterate   22    f= -1.57489D+01    |proj g|=  5.31741D-04
  ys=-5.158E-03  -gs= 3.806E-01 BFGS update SKIPPED

At iterate   23    f= -1.57890D+01    |proj g|=  5.28557D-04
  ys=-5.674E-05  -gs= 4.009E-02 BFGS update SKIPPED

At iterate   24    f= -1.57937D+01    |proj g|=  4.41902D-04
  ys=-7.983E-07  -gs= 4.667E-03 BFGS update SKIPPED

At iterate   25    f= -1.58701D+01    |proj g|=  4.35916D-04
  ys=-2.275E-04  -gs= 7.626E-02 BFGS update SKIPPED

At iterate   26    f= -1.58756D+01    |proj g|=  2.96303D-04
  ys=-1.330E-06  -gs= 5.496E-03 BFGS update SKIPPED

At iterate   27    f= -1.59483D+01    |proj g|=  2.88718D-04
  ys=-2.592E-04  -gs= 7.257E-02 BFGS update SKIPPED

At iterate   28    f= -1.59520D+01    |proj g|=  1.05300D-04
  ys=-1.023E-06  -gs= 3.771E-03 BFGS update SKIPPED

At iterate   29    f= -1.59863D+01    |proj g|=  1.01328D-04
  ys=-8.783E-05  -gs= 3.421E-02 BFGS update SKIPPED

At iterate   30    f= -1.59878D+01    |proj g|=  0.00000D+00

           * * *

Tit   = total number of iterations
Tnf   = total number of function evaluations
Tnint = total number of segments explored during Cauchy searches
Skip  = number of BFGS updates skipped
Nact  = number of active bounds at final generalized Cauchy point
Projg = norm of the final projected gradient
F     = final function value

           * * *

   N    Tit     Tnf  Tnint  Skip  Nact     Projg        F
  100     30    216     30    29    94   0.000D+00  -1.599D+01
  F =  -15.987807497724067     

CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL            

 Cauchy                time 0.000E+00 seconds.
 Subspace minimization time 0.000E+00 seconds.
 Line search           time 0.000E+00 seconds.

 Total User time 0.000E+00 seconds.

10.0 100.0

Comments (0)

  1. Log in to comment