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");
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");
415 _reason(TAO_CONVERGED_USER)
434 this->_is_initialized =
false;
436 PetscErrorCode ierr = TaoDestroy(&_tao);
438 libmesh_warning(
"Warning: TaoDestroy returned a non-zero error code which we ignored.");
450 this->_is_initialized =
true;
452 LibmeshPetscCall(TaoCreate(this->comm().get(),&_tao));
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));
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));
618 libMesh::out <<
"Tao optimization solver convergence/divergence reason: "
619 << TaoConvergedReasons[this->get_converged_reason()] << std::endl;
628 LibmeshPetscCall(TaoGetConvergedReason(_tao, &_reason));
630 return static_cast<int>(_reason);
This base class can be inherited from to provide interfaces to optimization solvers from different pa...
OptimizationSystem::ComputeInequalityConstraints * inequality_constraints_object
Object that computes the inequality constraints vector C_ineq(X).
OptimizationSystem::ComputeGradient * gradient_object
Object that computes the gradient grad_f(X) of the objective function at the input iterate X.
OptimizationSystem::ComputeEqualityConstraintsJacobian * equality_constraints_jacobian_object
Object that computes the Jacobian of C_eq(X).
const sys_type & system() const
OptimizationSystem::ComputeInequalityConstraintsJacobian * inequality_constraints_jacobian_object
Object that computes the Jacobian of C_ineq(X).
OptimizationSystem::ComputeHessian * hessian_object
Object that computes the Hessian H_f(X) of the objective function at the input iterate X.
OptimizationSystem::ComputeEqualityConstraints * equality_constraints_object
Object that computes the equality constraints vector C_eq(X).
OptimizationSystem::ComputeObjective * objective_object
Object that computes the objective function f(X) at the input iterate X.
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).
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).
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 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).
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).
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...
This System subclass enables us to assemble an objective function, gradient, Hessian and bounds for o...
const Parallel::Communicator & comm() const
This class provides a nice interface to the PETSc C-based data structures for parallel,...
virtual void close() override
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
This class provides a nice interface to the PETSc C-based AIJ data structures for parallel,...
This class provides a nice interface to PETSc's Vec object.
virtual void close() override
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
virtual void zero() override
Set all entries to zero.
void attach_dof_map(const DofMap &dof_map)
Set a pointer to the DofMap to use.
This class provides an interface to the Tao optimization solvers.
virtual void solve() override
Call the Tao solver.
virtual int get_converged_reason() override
virtual void init() override
Initialize data structures if not done so already.
virtual void print_converged_reason() override
Prints a useful message about why the latest optimization solve con(di)verged.
friend PetscErrorCode __libmesh_tao_hessian(Tao tao, Vec x, Mat h, Mat pc, void *ctx)
virtual void clear() noexcept override
Release all memory and clear data structures.
~TaoOptimizationSolver()
Destructor.
virtual void get_dual_variables() override
Get the current values of dual variables associated with inequality and equality constraints.
TaoOptimizationSolver(sys_type &system)
Constructor.
The libMesh namespace provides an interface to certain functionality in the library.
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
PetscErrorCode __libmesh_tao_gradient(Tao tao, Vec x, Vec g, void *ctx)
PetscErrorCode __libmesh_tao_objective(Tao tao, Vec x, PetscReal *objective, void *ctx)
PetscErrorCode __libmesh_tao_inequality_constraints_jacobian(Tao tao, Vec x, Mat J, Mat Jpre, void *ctx)
PetscErrorCode __libmesh_tao_equality_constraints_jacobian(Tao tao, Vec x, Mat J, Mat Jpre, void *ctx)
PetscErrorCode __libmesh_tao_equality_constraints(Tao tao, Vec x, Vec ce, void *ctx)
bool initialized()
Checks that library initialization has been done.
PetscErrorCode __libmesh_tao_hessian(Tao tao, Vec x, Mat h, Mat pc, void *ctx)
PetscErrorCode __libmesh_tao_inequality_constraints(Tao tao, Vec x, Vec cineq, void *ctx)