MAST
dot_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 
28 
29 #if MAST_ENABLE_DOT == 0
30  libmesh_error_msg("MAST configured without DOT support.");
31 #endif
32 }
33 
34 
35 
36 void
38 
39 #if MAST_ENABLE_DOT == 1
40  int
41  INFO = 0,
42  METHOD = 0, // METHOD == 0 or 1 means MMFD for constrained
43  // METHOD == 2 means SLP for constrained
44  // METHOD == 3 means SQP
45  // METHOD == 0 or 1 means BFGS for unconstrained
46  // METHOD == 2 means Fletcher-Reeves for unconstrained
47  IPRINT = 4, // IPRINT = 0, no output
48  // IPRINT = 1, internal params, initial information and results
49  // IPRINT = 2, same plus obj, X vec at each iter
50  // IPRINT = 3, same plus g, and critical constraint numbers
51  // IPRINT = 4, same plus gradients
52  // IPRINT = 5, same plus search direction
53  // IPRINT = 6, same plus set IPRM(11) = 1 and IPRM(12) = 1
54  // IPRINT = 7, same except set IPRM(12) = 2
55  NDV = _feval->n_vars(),
56  NCON = _feval->n_eq() + _feval->n_ineq(),
57  MINMAX = 0, // MINMAX = 0,-1 for minimization, = 1 for maximization
58  NRWK = std::max(NDV*NCON*10, 100000), // add a factor of 10 to be safe.
59  NRIWK = std::max(NDV*NCON*10, 300); // May need to be changed for individual problems
60 
61  libmesh_assert_greater(NDV, 0);
62  libmesh_assert_greater(NCON, 0);
63 
64  Real
65  OBJ = 0.;
66 
67  std::vector<int>
68  IPRM (20, 0),
69  IWK (NRIWK, 0);
70 
71  std::vector<double>
72  X (NDV, 0.),
73  XL (NDV, 0.),
74  XU (NDV, 0.),
75  G (NCON, 0.),
76  RPRM (20, 0.),
77  WK (NRWK, 0.),
78  DF0DX (NDV, 0.),
79  DFDX (NDV*NCON, 0.);
80 
81  std::vector<bool>
82  eval_grads(NCON, false);
83 
84 
85  _feval->init_dvar(X, XL, XU);
86 
87  unsigned int
88  ITER = 0;
89 
90  bool
91  obj_grad = false,
92  if_cont = true;
93 
94 
95  // user provided gradients
96  IPRM[0] = 1;
97 
98  while (if_cont) {
99 
100  dot_(&INFO,
101  &METHOD,
102  &IPRINT,
103  &NDV,
104  &NCON,
105  &X[0],
106  &XL[0],
107  &XU[0],
108  &OBJ,
109  &MINMAX,
110  &G[0],
111  &RPRM[0],
112  &IPRM[0],
113  &WK[0],
114  &NRWK,
115  &IWK[0],
116  &NRIWK);
117 
118 
119  if (INFO == 0) // INFO == 0 means optimization is complete
120  // INFO == 0 and IPRM(18) > 0 means an error has occurred
121  if_cont = false;
122  else if (INFO == 1) { // evaluate objective and constraints
123  std::fill(eval_grads.begin(), eval_grads.end(), false);
124  obj_grad = false;
125  }
126  else if (INFO == 2) {
127  std::fill(eval_grads.begin(), eval_grads.end(), true);
128  obj_grad = true;
129  }
130 
131  _feval->evaluate(X,
132  OBJ, obj_grad, DF0DX,
133  G, eval_grads, DFDX);
134 
135  // if gradients were requested, copy the data back to WK
136  if (INFO == 2) {
137  // first the objective function gradients
138  for (unsigned int i=0; i<NDV; i++) WK[i] = DF0DX[i];
139 
140  // next, the constraint gradients
141  // DOT requires gradients for only the active constraints
142  unsigned int
143  n_active_constrs = IPRM[19],
144  active_constr_id = 0;
145 
146  // the active constraints are listed in the first elements of
147  // IWK
148  for (unsigned int i=0; i<n_active_constrs; i++) {
149  active_constr_id = IWK[i];
150  // now copy the gradient values of this constraint
151  // wrt all DVs, which will be the row of DFDX
152  for (unsigned int j=0; j<NDV; j++)
153  WK[(i+1)*NDV+j] = DFDX[j*NCON+active_constr_id-1];
154  }
155  }
156 
157  _feval->_output_wrapper(ITER, X, OBJ, G, true);
158  ITER = ITER + 1;
159  }
160 
161  // write the final iteration to the output
162  _feval->_output_wrapper(ITER, X, OBJ, G, true);
163 
164 #endif // MAST_ENABLE_DOT 1
165 }
virtual void init_dvar(std::vector< Real > &x, std::vector< Real > &xmin, std::vector< Real > &xmax)=0
libMesh::Real Real
virtual void evaluate(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)=0
grads(k): Derivative of f_i(x) with respect to x_j, where k = (j-1)*M + i.
unsigned int n_ineq() const
void dot_(int *INFO, int *METHOD, int *IPRINT, int *NDV, int *NCON, double *X, double *XL, double *XU, double *OBJ, int *MINMAX, double *G, double *RPRM, int *IPRM, double *WK, int *NRWK, int *IWK, int *NRIWK)
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 ...
MAST::FunctionEvaluation * _feval
unsigned int n_eq() const