1 /* _______________________________________________________________________ 2 3 DAKOTA: Design Analysis Kit for Optimization and Terascale Applications 4 Copyright 2014-2020 National Technology & Engineering Solutions of Sandia, LLC (NTESS). 5 This software is distributed under the GNU Lesser General Public License. 6 For more information, see the README file in the top Dakota directory. 7 _______________________________________________________________________ */ 8 9 //- Class: NomadOptimizer 10 //- Description: Declaration of wrapper class for NOMAD solver 11 //- Owner: Patty Hough 12 //- Checked by: 13 //- Version: $Id$ 14 15 16 #include <DakotaOptimizer.hpp> 17 #include <ProblemDescDB.hpp> 18 19 #include <algorithm> 20 #include <sstream> 21 22 #include <nomad.hpp> 23 24 // Forward Declarations 25 class NomadOptimizer; 26 27 namespace Dakota { 28 29 /// Wrapper class for NOMAD Optimizer 30 31 /** NOMAD (is a Nonlinear Optimization by Mesh Adaptive Direct 32 search) is a simulation-based optimization package designed 33 to efficiently explore a design space using Mesh Adaptive 34 Search. 35 36 Mesh Adaptive Direct Search uses Meshes, discretizations of 37 the domain space of variables. It generates multiple meshes, 38 and as its name implies, it also adapts the refinement of 39 the meshes in order to find the best solution of a problem. 40 41 The objective of each iteration is to find points in a mesh 42 that improves the current solution. If a better solution is 43 not found, the next iteration is done over a finer mesh. 44 45 Each iteration is composed of two steps: Search and Poll. 46 The Search step finds any point in the mesh in an attempt 47 to find an improvement; while the Poll step generates trial 48 mesh points surrounding the current best current solution. 49 50 The NomadOptimizer is a wrapper for the NOMAD library. It 51 features the following attributes: \c max_function_evaluations, 52 \c display_format, \c display_all_evaluations, \c function_precision, 53 \c max_iterations. 54 */ 55 56 /** 57 * \brief A version of TraitsBase specialized for Nomad 58 * 59 */ 60 61 class NomadTraits: public TraitsBase 62 { 63 public: 64 65 /// default constructor NomadTraits()66 NomadTraits() { } 67 68 /// destructor ~NomadTraits()69 virtual ~NomadTraits() { } 70 71 /// A temporary query used in the refactor is_derived()72 virtual bool is_derived() { return true; } 73 74 /// Return the flag indicating whether method supports continuous variables supports_continuous_variables()75 bool supports_continuous_variables() { return true; } 76 77 /// Return the flag indicating whether method supports discrete variables supports_discrete_variables()78 bool supports_discrete_variables() { return true; } 79 80 /// Return the flag indicating whether method supports nonlinear equalities supports_nonlinear_equality()81 bool supports_nonlinear_equality() { return true; } 82 83 /// Return the format used for nonlinear equality constraints nonlinear_equality_format()84 NONLINEAR_EQUALITY_FORMAT nonlinear_equality_format() 85 { return NONLINEAR_EQUALITY_FORMAT::TRUE_EQUALITY; } 86 87 /// Return the flag indicating whether method supports nonlinear inequalities supports_nonlinear_inequality()88 bool supports_nonlinear_inequality() { return true; } 89 90 /// Return the format used for nonlinear inequality constraints nonlinear_inequality_format()91 NONLINEAR_INEQUALITY_FORMAT nonlinear_inequality_format() 92 { return NONLINEAR_INEQUALITY_FORMAT::ONE_SIDED_UPPER; } 93 }; 94 95 96 class NomadOptimizer : public Optimizer 97 { 98 public: 99 100 /// Constructor 101 /** NOMAD Optimizer Constructor 102 @param model DAKOTA Model object 103 */ 104 NomadOptimizer(ProblemDescDB& problem_db, Model &model); 105 106 /// alternate constructor for Iterator instantiations without DB 107 NomadOptimizer(Model& model); 108 109 /// Destructor 110 ~NomadOptimizer(); 111 112 // 113 //- Heading: Virtual member function redefinitions 114 // 115 116 /// Calls the NOMAD solver 117 void core_run(); 118 119 private: 120 121 // Forward Declaration 122 class Evaluator; 123 class Extended_Poll; 124 125 /// Convenience function for Parameter loading. 126 /** This function takes the Parameters provided by the user 127 in the DAKOTA model. 128 @param model NOMAD Model object 129 Variables for the stuff that must go in the parameters. 130 Will be filled by calling load_parameters after the 131 constructor to capture model recasts. 132 */ 133 void load_parameters(Model &model, NOMAD::Parameters &p); 134 135 /// Total across all types of variables 136 int numTotalVars; 137 138 /// Number of nonlinear inequality constraints after 139 /// put into the format required by NOMAD 140 int numNomadNonlinearIneqConstraints; 141 142 /// Algorithm control parameters passed to NOMAD 143 int randomSeed, maxBlackBoxEvals, maxIterations; 144 NOMAD::Double initMesh, minMesh, epsilon, vns; 145 146 /// Output control parameters passed to NOMAD 147 std::string outputFormat, historyFile; 148 bool displayAll; 149 150 /// Parameters needed for categorical neighbor construction 151 int numHops; 152 BitArray discreteSetIntCat, discreteSetRealCat; 153 RealMatrixArray discreteSetIntAdj, discreteSetRealAdj, discreteSetStrAdj; 154 RealMatrixArray categoricalAdjacency; 155 156 /// Pointer to Nomad initial point 157 NOMAD::Point initialPoint; 158 159 /// Pointer to Nomad upper bounds 160 NOMAD::Point upperBound; 161 162 /// Pointer to Nomad lower bounds 163 NOMAD::Point lowerBound; 164 165 /// defines use of surrogate in NOMAD 166 std::string useSurrogate; 167 }; 168 169 /// NOMAD-based Evaluator class. 170 171 /** The NOMAD process requires an evaluation step, which 172 calls the Simulation program. In the simplest version 173 of this call, NOMAD executes the black box executable, 174 which proceeds to write a file in a NOMAD-compatible 175 format, which NOMAD reads to continue the process. 176 177 Because DAKOTA files are different form NOMAD files, 178 and the simulations processed by DAKOTA already produce 179 DAKOTA-compatible files, we cannot use this method for 180 NOMAD. Instead, we implement the \c NomadEvaluator class, 181 which takes the NOMAD inputs and passes them to DAKOTA's 182 Interface for processing. The evaluator then passes 183 the evaluation Responses into the NOMAD objects for 184 further analysis. 185 */ 186 187 class NomadOptimizer::Evaluator : public NOMAD::Evaluator 188 { 189 private: 190 191 /// map NOMAD evaluation point to Dakota model 192 void set_variables(const NOMAD::Eval_Point &x) const; 193 /// evaluate the Dakota model (block or not, but don't collect response) 194 void eval_model(bool allow_asynch, const NOMAD::Eval_Point& x) const; 195 /// map Dakota model responses to NOMAD evaluation point 196 void get_responses(const RealVector& ftn_vals, NOMAD::Eval_Point &x) const; 197 198 Model& _model; 199 int n_cont,n_disc_int, n_disc_real; 200 201 /// Number of nonlinear constraints after put into Nomad format 202 int numNomadNonlinearIneqConstr, numNomadNonlinearEqConstr; 203 204 /// map from Dakota constraint number to Nomad constraint number 205 std::vector<int> constrMapIndices; 206 207 /// multipliers for constraint transformations 208 std::vector<double> constrMapMultipliers; 209 210 /// offsets for constraint transformations 211 std::vector<double> constrMapOffsets; 212 213 /// defines use of surrogate in NOMAD 214 std::string useSgte; 215 216 public: 217 218 /// Constructor 219 /** NOMAD Evaluator Constructor 220 @param p NOMAD Parameters object 221 @param model DAKOTA Model object 222 */ 223 Evaluator(const NOMAD::Parameters &p, Model& model); 224 225 /// Destructor 226 ~Evaluator(void); 227 228 /// Main Evaluation Method 229 /** Method that handles the communication between 230 the NOMAD search process and the Black Box 231 Evaluation managed by DAKOTA's Interface. 232 @param x Object that contains the points that 233 need to evaluated. Once the evaluation 234 is completed, this object also stores 235 the output back to be read by NOMAD. 236 @param h_max Current value of the barrier 237 parameter. Not used in this 238 implementation. 239 @param count_eval Flag that indicates whether 240 this evaluation counts 241 towards the max number of 242 evaluations, often set to 243 \c false when the evaluation 244 does not meet certain costs 245 during expensive evaluations. 246 Not used in this 247 implementation. 248 @return \c true if the evaluation was successful; 249 \c false otherwise. 250 */ 251 bool eval_x (NOMAD::Eval_Point &x, 252 const NOMAD::Double &h_max, 253 bool &count_eval) const; 254 255 /// multi-point variant of evaluator 256 bool eval_x ( std::list<NOMAD::Eval_Point *>& x, 257 const NOMAD::Double& h_max, 258 std::list<bool>& count_eval ) const; 259 260 /// publishes constraint transformation set_constraint_map(int numNomadNonlinearIneqConstraints,int numNomadNonlinearEqConstraints,std::vector<int> constraintMapIndices,std::vector<double> constraintMapMultipliers,std::vector<double> constraintMapOffsets)261 void set_constraint_map (int numNomadNonlinearIneqConstraints, 262 int numNomadNonlinearEqConstraints, 263 std::vector<int> constraintMapIndices, 264 std::vector<double> constraintMapMultipliers, 265 std::vector<double> constraintMapOffsets) 266 { numNomadNonlinearIneqConstr = numNomadNonlinearIneqConstraints; 267 numNomadNonlinearEqConstr = numNomadNonlinearEqConstraints, 268 constrMapIndices = constraintMapIndices; 269 constrMapMultipliers = constraintMapMultipliers; 270 constrMapOffsets = constraintMapOffsets;} 271 272 /// publishes surrogate usage set_surrogate_usage(std::string useSurrogate)273 void set_surrogate_usage (std::string useSurrogate) 274 { useSgte = useSurrogate;} 275 }; 276 277 class NomadOptimizer::Extended_Poll : public NOMAD::Extended_Poll 278 { 279 private: 280 281 RealMatrixArray &adjacency_matrix; 282 int nHops; 283 284 public: 285 286 /// Constructor Extended_Poll(NOMAD::Parameters & p,RealMatrixArray & categoricalAdjacency,int numHops)287 Extended_Poll(NOMAD::Parameters &p, RealMatrixArray &categoricalAdjacency, 288 int numHops) : NOMAD::Extended_Poll(p), 289 adjacency_matrix(categoricalAdjacency), 290 nHops(numHops) {}; 291 292 /// Destructor ~Extended_Poll(void)293 ~Extended_Poll(void){}; 294 295 /// Construct the extended poll points. Called by NOMAD. 296 void construct_extended_points(const NOMAD::Eval_Point &nomad_point); 297 298 /// Recursive helper function to construct the multi-hop neighbors 299 /// derived from adjacency matrices and returned to 300 /// construct_extended_points. 301 void construct_multihop_neighbors(NOMAD::Point &base_point, 302 NOMAD::Signature point_signature, 303 RealMatrixArray::iterator rma_iter, 304 size_t last_cat_index, int num_hops); 305 }; 306 307 } // namespace DAKOTA 308