20 #include "libmesh/libmesh_common.h" 22 #if defined(LIBMESH_HAVE_PETSC_TAO) && !defined(LIBMESH_USE_COMPLEX_NUMBERS) 28 #include "libmesh/libmesh_logging.h" 29 #include "libmesh/petsc_vector.h" 30 #include "libmesh/petsc_matrix.h" 31 #include "libmesh/dof_map.h" 32 #include "libmesh/tao_optimization_solver.h" 33 #include "libmesh/equation_systems.h" 54 LOG_SCOPE(
"objective()",
"TaoOptimizationSolver");
83 sys.get_dof_map().enforce_constraints_exactly(sys, sys.current_local_solution.get());
88 libmesh_error_msg(
"Objective function not defined in __libmesh_tao_objective");
102 LOG_SCOPE(
"gradient()",
"TaoOptimizationSolver");
134 sys.get_dof_map().enforce_constraints_exactly(sys, sys.current_local_solution.get());
139 libmesh_error_msg(
"Gradient function not defined in __libmesh_tao_gradient");
153 LOG_SCOPE(
"hessian()",
"TaoOptimizationSolver");
182 hessian.attach_dof_map(sys.get_dof_map());
185 sys.get_dof_map().enforce_constraints_exactly(sys, sys.current_local_solution.get());
194 libmesh_error_msg(
"Hessian function not defined in __libmesh_tao_hessian");
210 LOG_SCOPE(
"equality_constraints()",
"TaoOptimizationSolver");
239 eq_constraints.
zero();
242 sys.get_dof_map().enforce_constraints_exactly(sys, sys.current_local_solution.get());
247 libmesh_error_msg(
"Constraints function not defined in __libmesh_tao_equality_constraints");
249 eq_constraints.close();
262 LOG_SCOPE(
"equality_constraints_jacobian()",
"TaoOptimizationSolver");
291 sys.get_dof_map().enforce_constraints_exactly(sys, sys.current_local_solution.get());
296 libmesh_error_msg(
"Constraints function not defined in __libmesh_tao_equality_constraints_jacobian");
311 LOG_SCOPE(
"inequality_constraints()",
"TaoOptimizationSolver");
340 ineq_constraints.
zero();
343 sys.get_dof_map().enforce_constraints_exactly(sys, sys.current_local_solution.get());
348 libmesh_error_msg(
"Constraints function not defined in __libmesh_tao_inequality_constraints");
350 ineq_constraints.close();
363 LOG_SCOPE(
"inequality_constraints_jacobian()",
"TaoOptimizationSolver");
392 sys.get_dof_map().enforce_constraints_exactly(sys, sys.current_local_solution.get());
397 libmesh_error_msg(
"Constraints function not defined in __libmesh_tao_inequality_constraints_jacobian");
412 template <
typename T>
415 _reason(TAO_CONVERGED_USER)
421 template <
typename T>
429 template <
typename T>
436 PetscErrorCode ierr = TaoDestroy(&_tao);
438 libmesh_warning(
"Warning: TaoDestroy returned a non-zero error code which we ignored.");
444 template <
typename T>
452 LibmeshPetscCall(TaoCreate(this->comm().
get(),&_tao));
456 template <
typename T>
459 LOG_SCOPE(
"solve()",
"TaoOptimizationSolver");
463 this->system().solution->zero();
467 PetscVector<T> * x = cast_ptr<PetscVector<T> *>(this->system().solution.get());
468 PetscVector<T> * ceq = cast_ptr<PetscVector<T> *>(this->system().C_eq.get());
469 PetscMatrixBase<T> * ceq_jac = cast_ptr<PetscMatrixBase<T> *>(this->system().C_eq_jac.get());
470 PetscVector<T> * cineq = cast_ptr<PetscVector<T> *>(this->system().C_ineq.get());
471 PetscMatrixBase<T> * cineq_jac = cast_ptr<PetscMatrixBase<T> *>(this->system().C_ineq_jac.get());
472 PetscVector<T> * lb = cast_ptr<PetscVector<T> *>(&this->system().get_vector(
"lower_bounds"));
473 PetscVector<T> * ub = cast_ptr<PetscVector<T> *>(&this->system().get_vector(
"upper_bounds"));
483 LibmeshPetscCall(TaoSetFromOptions(_tao));
493 #if PETSC_VERSION_LESS_THAN(3,7,0) 494 LibmeshPetscCall(TaoSetTolerances(_tao,
498 this->objective_function_relative_tolerance,
501 LibmeshPetscCall(TaoSetTolerances(_tao,
503 this->objective_function_relative_tolerance,
509 LibmeshPetscCall(TaoSetMaximumFunctionEvaluations(_tao, this->max_objective_function_evaluations));
517 #if PETSC_VERSION_LESS_THAN(3,17,0) 518 LibmeshPetscCall(TaoSetInitialVector(_tao, x->vec()));
520 LibmeshPetscCall(TaoSetSolution(_tao, x->vec()));
527 #if PETSC_VERSION_LESS_THAN(3,17,0) 533 if (this->gradient_object)
534 #if PETSC_VERSION_LESS_THAN(3,17,0) 540 if (this->hessian_object)
541 #if PETSC_VERSION_LESS_THAN(3,17,0) 547 if (this->lower_and_upper_bounds_object)
550 this->lower_and_upper_bounds_object->lower_and_upper_bounds(this->system());
552 LibmeshPetscCall(TaoSetVariableBounds(_tao,
557 if (this->equality_constraints_object)
560 if (this->equality_constraints_jacobian_object)
561 LibmeshPetscCall(TaoSetJacobianEqualityRoutine(_tao,
568 if (this->inequality_constraints_object)
572 if (this->inequality_constraints_jacobian_object)
573 LibmeshPetscCall(TaoSetJacobianInequalityRoutine(_tao,
580 LibmeshPetscCall(TaoSetFromOptions(_tao));
583 LibmeshPetscCall(TaoSolve(_tao));
589 this->system().get_dof_map().enforce_constraints_exactly(this->system());
592 LibmeshPetscCall(TaoGetConvergedReason(_tao, &_reason));
596 template <
typename T>
599 LOG_SCOPE(
"get_dual_variables()",
"TaoOptimizationSolver");
602 cast_ptr<PetscVector<T> *>(this->system().lambda_eq.get());
604 cast_ptr<PetscVector<T> *>(this->system().lambda_ineq.get());
606 Vec lambda_eq_petsc_vec = lambda_eq_petsc->
vec();
607 Vec lambda_ineq_petsc_vec = lambda_ineq_petsc->vec();
609 LibmeshPetscCall(TaoGetDualVariables(_tao,
610 &lambda_eq_petsc_vec,
611 &lambda_ineq_petsc_vec));
615 template <
typename T>
618 libMesh::out <<
"Tao optimization solver convergence/divergence reason: " 619 << TaoConvergedReasons[this->get_converged_reason()] << std::endl;
624 template <
typename T>
628 LibmeshPetscCall(TaoGetConvergedReason(_tao, &_reason));
630 return static_cast<int>(_reason);
642 #endif // #if defined(LIBMESH_HAVE_PETSC_TAO) && !defined(LIBMESH_USE_COMPLEX_NUMBERS) OptimizationSystem::ComputeObjective * objective_object
Object that computes the objective function f(X) at the input iterate X.
This class provides a nice interface to PETSc's Vec object.
This class provides an interface to the Tao optimization solvers.
virtual void gradient(const NumericVector< Number > &X, NumericVector< Number > &grad_f, sys_type &S)=0
This function will be called to compute the gradient of the objective function, and must be implement...
virtual void zero() override
Set all entries to zero.
This class provides a nice interface to the PETSc C-based data structures for parallel, sparse matrices.
virtual void solve() override
Call the Tao solver.
virtual void hessian(const NumericVector< Number > &X, SparseMatrix< Number > &H_f, sys_type &S)=0
This function will be called to compute the Hessian of the objective function, and must be implemente...
virtual void inequality_constraints_jacobian(const NumericVector< Number > &X, SparseMatrix< Number > &C_ineq_jac, sys_type &S)=0
This function will be called to evaluate the Jacobian of C_ineq(X).
const Parallel::Communicator & comm() const
OptimizationSystem::ComputeGradient * gradient_object
Object that computes the gradient grad_f(X) of the objective function at the input iterate X...
virtual int get_converged_reason() override
The libMesh namespace provides an interface to certain functionality in the library.
virtual void print_converged_reason() override
Prints a useful message about why the latest optimization solve con(di)verged.
OptimizationSystem::ComputeHessian * hessian_object
Object that computes the Hessian H_f(X) of the objective function at the input iterate X...
virtual void swap(NumericVector< T > &v) override
Swaps the contents of this with v.
OptimizationSystem::ComputeInequalityConstraints * inequality_constraints_object
Object that computes the inequality constraints vector C_ineq(X).
PetscErrorCode __libmesh_tao_gradient(Tao tao, Vec x, Vec g, void *ctx)
PetscErrorCode __libmesh_tao_hessian(Tao tao, Vec x, Mat h, Mat pc, void *ctx)
OptimizationSystem::ComputeEqualityConstraintsJacobian * equality_constraints_jacobian_object
Object that computes the Jacobian of C_eq(X).
bool _is_initialized
Flag that tells if init() has been called.
TaoOptimizationSolver(sys_type &system)
Constructor.
This System subclass enables us to assemble an objective function, gradient, Hessian and bounds for o...
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
virtual void equality_constraints(const NumericVector< Number > &X, NumericVector< Number > &C_eq, sys_type &S)=0
This function will be called to evaluate the equality constraints vector C_eq(X). ...
PetscErrorCode __libmesh_tao_objective(Tao tao, Vec x, PetscReal *objective, void *ctx)
virtual void clear() noexcept override
Release all memory and clear data structures.
const sys_type & system() const
void attach_dof_map(const DofMap &dof_map)
Set a pointer to the DofMap to use.
virtual Number objective(const NumericVector< Number > &X, sys_type &S)=0
This function will be called to compute the objective function to be minimized, and must be implement...
virtual void equality_constraints_jacobian(const NumericVector< Number > &X, SparseMatrix< Number > &C_eq_jac, sys_type &S)=0
This function will be called to evaluate the Jacobian of C_eq(X).
~TaoOptimizationSolver()
Destructor.
This base class can be inherited from to provide interfaces to optimization solvers from different pa...
PetscErrorCode __libmesh_tao_equality_constraints_jacobian(Tao tao, Vec x, Mat J, Mat Jpre, void *ctx)
This class provides a nice interface to the PETSc C-based AIJ data structures for parallel...
bool initialized()
Checks that library initialization has been done.
PetscErrorCode __libmesh_tao_equality_constraints(Tao tao, Vec x, Vec ce, void *ctx)
PetscErrorCode __libmesh_tao_inequality_constraints_jacobian(Tao tao, Vec x, Mat J, Mat Jpre, void *ctx)
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
PetscErrorCode __libmesh_tao_inequality_constraints(Tao tao, Vec x, Vec cineq, void *ctx)
virtual void init() override
Initialize data structures if not done so already.
virtual void get_dual_variables() override
Get the current values of dual variables associated with inequality and equality constraints.
virtual void inequality_constraints(const NumericVector< Number > &X, NumericVector< Number > &C_ineq, sys_type &S)=0
This function will be called to evaluate the equality constraints vector C_ineq(X).
OptimizationSystem::ComputeInequalityConstraintsJacobian * inequality_constraints_jacobian_object
Object that computes the Jacobian of C_ineq(X).
OptimizationSystem::ComputeEqualityConstraints * equality_constraints_object
Object that computes the equality constraints vector C_eq(X).