22 #if defined(LIBMESH_HAVE_NLOPT) && !defined(LIBMESH_USE_COMPLEX_NUMBERS) 42 LOG_SCOPE(
"objective()",
"NloptOptimizationSolver");
53 sys.solution->set(i, x[i]);
56 sys.solution->close();
59 sys.get_dof_map().enforce_constraints_exactly(sys);
72 libmesh_error_msg(
"Objective function not defined in __libmesh_nlopt_objective");
84 libmesh_assert(sys.rhs->size() == n);
86 std::vector<double> grad;
87 sys.rhs->localize_to_one(grad);
88 for (
unsigned int i = 0; i < n; ++i)
89 gradient[i] = grad[i];
92 libmesh_error_msg(
"Gradient function not defined in __libmesh_nlopt_objective");
114 LOG_SCOPE(
"equality_constraints()",
"NloptOptimizationSolver");
116 libmesh_assert(
data);
126 if (sys.solution->size() != n)
127 libmesh_error_msg(
"Error: Input vector x has different length than sys.solution!");
130 sys.solution->set(i, x[i]);
131 sys.solution->close();
134 sys.get_dof_map().enforce_constraints_exactly(sys);
153 for (
unsigned int i = 0; i < m; ++i)
154 result[i] = (*sys.C_eq)(i);
170 sys.C_eq_jac->close();
174 for (
const auto & dof_index : sys.eq_constraint_jac_sparsity[i])
175 gradient[n*i+dof_index] = (*sys.C_eq_jac)(i,dof_index);
178 libmesh_error_msg(
"Jacobian function not defined in __libmesh_nlopt_equality_constraints");
183 libmesh_error_msg(
"Constraints function not defined in __libmesh_nlopt_equality_constraints");
194 LOG_SCOPE(
"inequality_constraints()",
"NloptOptimizationSolver");
196 libmesh_assert(
data);
206 if (sys.solution->size() != n)
207 libmesh_error_msg(
"Error: Input vector x has different length than sys.solution!");
210 sys.solution->set(i, x[i]);
211 sys.solution->close();
214 sys.get_dof_map().enforce_constraints_exactly(sys);
233 for (
unsigned int i = 0; i < m; ++i)
234 result[i] = (*sys.C_ineq)(i);
250 sys.C_ineq_jac->close();
254 for (
const auto & dof_index : sys.ineq_constraint_jac_sparsity[i])
255 gradient[n*i+dof_index] = (*sys.C_ineq_jac)(i,dof_index);
258 libmesh_error_msg(
"Jacobian function not defined in __libmesh_nlopt_inequality_constraints");
263 libmesh_error_msg(
"Constraints function not defined in __libmesh_nlopt_inequality_constraints");
272 template <
typename T>
277 _result(NLOPT_SUCCESS),
279 _constraints_tolerance(1.e-8)
287 libmesh_error_msg(
"The NloptOptimizationSolver should not be used with dof_id_type != unsigned int.");
292 template <
typename T>
300 template <
typename T>
313 template <
typename T>
322 std::string nlopt_algorithm_name =
"LD_SLSQP";
326 nlopt_algorithm_name);
329 auto it = _nlopt_algorithms.find(nlopt_algorithm_name);
331 if (it == _nlopt_algorithms.end())
332 libmesh_error_msg(
"Invalid nlopt algorithm requested on command line: " \
333 << nlopt_algorithm_name);
335 _opt = nlopt_create(it->second, this->system().solution->size());
341 template <
typename T>
344 LOG_SCOPE(
"solve()",
"NloptOptimizationSolver");
348 unsigned int nlopt_size = this->system().solution->size();
351 libmesh_assert( this->objective_object );
356 nlopt_set_min_objective(_opt,
360 libmesh_error_msg(
"NLopt failed to set min objective: " <<
ierr);
363 if (this->lower_and_upper_bounds_object)
366 this->lower_and_upper_bounds_object->lower_and_upper_bounds(this->system());
368 std::vector<Real> nlopt_lb(nlopt_size);
369 std::vector<Real> nlopt_ub(nlopt_size);
370 for (
unsigned int i = 0; i < nlopt_size; ++i)
372 nlopt_lb[i] = this->system().get_vector(
"lower_bounds")(i);
373 nlopt_ub[i] = this->system().get_vector(
"upper_bounds")(i);
376 nlopt_set_lower_bounds(_opt, nlopt_lb.data());
377 nlopt_set_upper_bounds(_opt, nlopt_ub.data());
381 if (this->equality_constraints_object)
386 std::vector<double> equality_constraints_tolerances(this->system().C_eq->size(),
387 _constraints_tolerance);
393 nlopt_add_equality_mconstraint(_opt,
394 equality_constraints_tolerances.size(),
397 equality_constraints_tolerances.data());
400 libmesh_error_msg(
"NLopt failed to add equality constraint: " <<
ierr);
404 if (this->inequality_constraints_object)
407 std::vector<double> inequality_constraints_tolerances(this->system().C_ineq->size(),
408 _constraints_tolerance);
410 nlopt_add_inequality_mconstraint(_opt,
411 inequality_constraints_tolerances.size(),
414 inequality_constraints_tolerances.data());
418 nlopt_set_ftol_rel(_opt, this->objective_function_relative_tolerance);
421 nlopt_set_maxeval(_opt, this->max_objective_function_evaluations);
424 this->_iteration_count = 0;
427 std::vector<Real> x(nlopt_size);
429 _result = nlopt_optimize(_opt, x.data(), &min_val);
437 << this->get_iteration_count()
443 template <
typename T>
446 libMesh::out <<
"NLopt optimization solver convergence/divergence reason: " 447 << this->get_converged_reason() << std::endl;
452 template <
typename T>
455 return static_cast<int>(_result);
467 #endif // #if defined(LIBMESH_HAVE_NLOPT) && !defined(LIBMESH_USE_COMPLEX_NUMBERS) ~NloptOptimizationSolver()
OptimizationSystem::ComputeObjective * objective_object
virtual void init() override
virtual void gradient(const NumericVector< Number > &X, NumericVector< Number > &grad_f, sys_type &S)=0
virtual void inequality_constraints_jacobian(const NumericVector< Number > &X, SparseMatrix< Number > &C_ineq_jac, sys_type &S)=0
IntRange< std::size_t > index_range(const std::vector< T > &vec)
OptimizationSystem::ComputeGradient * gradient_object
OptimizationSystem::ComputeInequalityConstraints * inequality_constraints_object
virtual void solve() override
OptimizationSystem::ComputeEqualityConstraintsJacobian * equality_constraints_jacobian_object
dof_id_type numeric_index_type
NloptOptimizationSolver(sys_type &system)
void init(triangulateio &t)
T command_line_next(std::string name, T value)
virtual void equality_constraints(const NumericVector< Number > &X, NumericVector< Number > &C_eq, sys_type &S)=0
virtual void clear() override
void __libmesh_nlopt_inequality_constraints(unsigned m, double *result, unsigned n, const double *x, double *gradient, void *data)
const sys_type & system() const
virtual Number objective(const NumericVector< Number > &X, sys_type &S)=0
virtual void print_converged_reason() override
virtual void equality_constraints_jacobian(const NumericVector< Number > &X, SparseMatrix< Number > &C_eq_jac, sys_type &S)=0
unsigned & get_iteration_count()
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
double __libmesh_nlopt_objective(unsigned n, const double *x, double *gradient, void *data)
bool on_command_line(std::string arg)
OStreamProxy out(std::cout)
virtual int get_converged_reason() override
virtual void inequality_constraints(const NumericVector< Number > &X, NumericVector< Number > &C_ineq, sys_type &S)=0
OptimizationSystem::ComputeInequalityConstraintsJacobian * inequality_constraints_jacobian_object
OptimizationSystem::ComputeEqualityConstraints * equality_constraints_object
void __libmesh_nlopt_equality_constraints(unsigned m, double *result, unsigned n, const double *x, double *gradient, void *data)