MAST
nlopt_optimization_interface.cpp
Go to the documentation of this file.
1 /*
2  * MAST: Multidisciplinary-design Adaptation and Sensitivity Toolkit
3  * Copyright (C) 2013-2019 Manav Bhatia
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 // MAST includes
23 #include "base/mast_config.h"
24 
25 double
27  const double* x,
28  double* grad,
29  void* f_data) {
30 
32  opt_interface = static_cast<MAST::NLOptOptimizationInterface*>(f_data);
33 
34  return
35  opt_interface->objective_evaluation(n, x, grad);
36 }
37 
38 
39 void
41  double *result,
42  unsigned n,
43  const double *x,
44  double *gradient, /* NULL if not needed */
45  void *func_data) {
46  //
47  // \partial c_i/\partial x_j is stored in grad[i*n + j]
48  //
50  opt_interface = static_cast<MAST::NLOptOptimizationInterface*>(func_data);
51 
52  opt_interface->inequality_constraint_evaluation(m, result, n, x, gradient);
53 }
54 
55 
56 
59 _iter (0),
60 _alg (alg) {
61 
62 }
63 
64 
65 void
67 
68  // make sure that all processes have the same problem setup
70 
71  int
72  n = _feval->n_vars(),
73  m_eq = _feval->n_eq(),
74  m_ineq = _feval->n_ineq(),
75  n_rel_change_iters = _feval->n_iters_relative_change();
76  _iter = 0;
77 
78  // equality constraints are not currently handled in this API
79  libmesh_assert_equal_to(m_eq, 0);
80 
81  Real
82  obj = 0.,
83  tol = 1.e-3;
84 
85  nlopt_result
86  res;
87 
88  libmesh_assert_greater(n, 0);
89 
90  std::vector<Real>
91  xval (n, 0.),
92  xmin (n, 0.),
93  xmax (n, 0.);
94 
95 
97  // initialize the optimizer object
99  nlopt_opt
100  opt = nlopt_create(_alg, n);
101 
103  // set variable bounds
105  _feval->_init_dvar_wrapper(xval, xmin, xmax);
106 
107  res = nlopt_set_lower_bounds(opt, &xmin[0]);
108  libmesh_assert_equal_to(res, NLOPT_SUCCESS);
109 
110  res = nlopt_set_upper_bounds(opt, &xmax[0]);
111  libmesh_assert_equal_to(res, NLOPT_SUCCESS);
112 
114  // attach the objective and constraint functions
116  res = nlopt_set_min_objective(opt, _mast_nlopt_objective_function, (void*)this);
117  libmesh_assert_equal_to(res, NLOPT_SUCCESS);
118 
119  // nothing done about equality constraints so far.
120  res = nlopt_add_inequality_mconstraint(opt,
121  m_ineq,
123  (void*)this,
124  &tol);
125  libmesh_assert_equal_to(res, NLOPT_SUCCESS);
126 
127 
129  // optimize
131  res = nlopt_optimize(opt, &xval[0], &obj);
132  libmesh_assert_equal_to(res, NLOPT_SUCCESS);
133 
135  // clean up the optimizer object
137  nlopt_destroy(opt);
138 }
139 
140 
141 
142 Real
144  const double* x,
145  double* grad) {
146 
147  libmesh_assert_equal_to(n, _feval->n_vars());
148 
149  unsigned int
150  n_constr = _feval->n_eq() + _feval->n_ineq();
151 
152  std::vector<Real>
153  xvals(x, x+n),
154  fvals(n_constr, 0.),
155  df0dx(n, 0.),
156  dfdx (n*n_constr, 0.);
157 
158  std::vector<bool>
159  eval_grads(n_constr, false);
160 
161  Real
162  f0val = 0.;
163 
164  // output the data
165  if (!grad) {
166  _feval->_output_wrapper(_iter, xvals, f0val, fvals, true);
167  _iter++;
168  }
169 
170  _feval->_evaluate_wrapper(xvals,
171  f0val, grad!=nullptr, df0dx,
172  fvals, eval_grads, dfdx);
173 
174  if (grad)
175  for (unsigned int i=0; i<n; i++) grad[i] = df0dx[i];
176 
177  return f0val;
178 }
179 
180 
181 void
184  double *result,
185  unsigned n,
186  const double *x,
187  double *gradient) {
188 
189 
190  libmesh_assert_equal_to(n, _feval->n_vars());
191 
192  unsigned int
193  n_constr = _feval->n_eq() + _feval->n_ineq();
194 
195  libmesh_assert_equal_to(m, n_constr);
196 
197  std::vector<Real>
198  xvals(x, x+n),
199  fvals(n_constr, 0.),
200  df0dx(n, 0.),
201  dfdx (n*n_constr, 0.);
202 
203  std::vector<bool>
204  eval_grads(n_constr, gradient!=nullptr);
205 
206  Real
207  f0val;
208 
209  _feval->_evaluate_wrapper(xvals,
210  f0val, false, df0dx,
211  fvals, eval_grads, dfdx);
212 
213  if (gradient) {
214 
215  //
216  // NLOpt requires the derivatives to be in this form
217  // \partial c_i/\partial x_j is stored in grad[i*n + j]
218  //
219  // However, the function evaluation returns the following:
220  // grads(k): Derivative of f_i(x) with respect
221  // to x_j, where k = (j-1)*M + i.
222  //
223  // Therefore, we translate the values into the proper order
224 
225  for (unsigned int i=0; i<m; i++)
226  for (unsigned int j=0; j<n; j++)
227  gradient[i*n+j] = dfdx[j*m+i];
228  }
229 }
230 
void sanitize_parallel()
make sure that the analysis is setup consistently across all parallel processes
Real objective_evaluation(unsigned n, const double *x, double *grad)
Computes and.
libMesh::Real Real
unsigned int n_ineq() const
virtual void _evaluate_wrapper(const std::vector< Real > &dvars, Real &obj, bool eval_obj_grad, std::vector< Real > &obj_grad, std::vector< Real > &fvals, std::vector< bool > &eval_grads, std::vector< Real > &grads)
This serves as a wrapper around evaluate() and makes sure that the derived class&#39;s implementation is ...
Provides the basic interface API for classes the provide implement optimization problems.
unsigned int n_vars() const
virtual void _output_wrapper(unsigned int iter, const std::vector< Real > &x, Real obj, const std::vector< Real > &fval, bool if_write_to_optim_file)
This serves as a wrapper around evaluate() and makes sure that the derived class&#39;s implementation is ...
double _mast_nlopt_objective_function(unsigned n, const double *x, double *grad, void *f_data)
MAST::FunctionEvaluation * _feval
virtual void _init_dvar_wrapper(std::vector< Real > &x, std::vector< Real > &xmin, std::vector< Real > &xmax)
This serves as a wrapper around init_dvar() and makes sure that the derived class&#39;s implementation pr...
unsigned int n_eq() const
unsigned int n_iters_relative_change() const
void inequality_constraint_evaluation(unsigned m, double *result, unsigned n, const double *x, double *gradient)
Computes the m inequality constraints and.
void _mast_nlopt_ineq_constr_mfunc(unsigned m, double *result, unsigned n, const double *x, double *gradient, void *func_data)
nlopt_algorithm _alg
NLOpt algorithm to use.