Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 :
4 : // This library is free software; you can redistribute it and/or
5 : // modify it under the terms of the GNU Lesser General Public
6 : // License as published by the Free Software Foundation; either
7 : // version 2.1 of the License, or (at your option) any later version.
8 :
9 : // This library is distributed in the hope that it will be useful,
10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : // Lesser General Public License for more details.
13 :
14 : // You should have received a copy of the GNU Lesser General Public
15 : // License along with this library; if not, write to the Free Software
16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 :
18 :
19 :
20 : #ifndef LIBMESH_TAO_OPTIMIZATION_SOLVER_H
21 : #define LIBMESH_TAO_OPTIMIZATION_SOLVER_H
22 :
23 : #include "libmesh/libmesh_config.h"
24 :
25 : // Petsc include files.
26 : #if defined(LIBMESH_HAVE_PETSC_TAO) && !defined(LIBMESH_USE_COMPLEX_NUMBERS)
27 :
28 : // Local includes
29 : #include "libmesh/petsc_macro.h"
30 : #include "libmesh/optimization_solver.h"
31 :
32 : // Include header for the Tao optimization library
33 : #ifdef I
34 : # define LIBMESH_SAW_I
35 : #endif
36 : #include <petsctao.h>
37 : #ifndef LIBMESH_SAW_I
38 : # undef I // Avoid complex.h contamination
39 : #endif
40 :
41 : namespace libMesh
42 : {
43 :
44 : // Allow users access to these functions in case they want to reuse them. Users shouldn't
45 : // need access to these most of the time as they are used internally by this object.
46 : extern "C"
47 : {
48 : PetscErrorCode __libmesh_tao_objective (Tao tao, Vec x, PetscReal * objective, void * ctx);
49 : PetscErrorCode __libmesh_tao_gradient(Tao tao, Vec x, Vec g, void * ctx);
50 : PetscErrorCode __libmesh_tao_hessian(Tao tao, Vec x, Mat h, Mat pc, void * ctx);
51 : PetscErrorCode __libmesh_tao_equality_constraints(Tao tao, Vec x, Vec ce, void * ctx);
52 : PetscErrorCode __libmesh_tao_equality_constraints_jacobian(Tao tao, Vec x, Mat J, Mat Jpre, void * ctx);
53 : PetscErrorCode __libmesh_tao_inequality_constraints(Tao tao, Vec x, Vec cineq, void * ctx);
54 : PetscErrorCode __libmesh_tao_inequality_constraints_jacobian(Tao tao, Vec x, Mat J, Mat Jpre, void * ctx);
55 : }
56 :
57 : /**
58 : * This class provides an interface to the Tao optimization solvers.
59 : *
60 : * \author David Knezevic
61 : * \date 2015
62 : */
63 : template <typename T>
64 : class TaoOptimizationSolver : public OptimizationSolver<T>
65 : {
66 : public:
67 :
68 : /**
69 : * The type of system that we use in conjunction with this solver.
70 : */
71 : typedef OptimizationSystem sys_type;
72 :
73 : /**
74 : * Constructor. Initializes Tao data structures.
75 : */
76 : explicit
77 : TaoOptimizationSolver (sys_type & system);
78 :
79 : /**
80 : * Destructor.
81 : */
82 : ~TaoOptimizationSolver ();
83 :
84 : /**
85 : * Release all memory and clear data structures.
86 : * clear() is called from the destructor, so it should not throw.
87 : */
88 : virtual void clear () noexcept override;
89 :
90 : /**
91 : * Initialize data structures if not done so already.
92 : */
93 : virtual void init () override;
94 :
95 : /**
96 : * \returns The raw PETSc Tao context pointer.
97 : */
98 0 : Tao tao() { this->init(); return _tao; }
99 :
100 : /**
101 : * Call the Tao solver.
102 : */
103 : virtual void solve () override;
104 :
105 : /**
106 : * Get the current values of dual variables associated with
107 : * inequality and equality constraints. The variables will
108 : * be stored in _system.lambda_eq and _system.lambda_ineq.
109 : */
110 : virtual void get_dual_variables() override;
111 :
112 : /**
113 : * Prints a useful message about why the latest optimization solve
114 : * con(di)verged.
115 : */
116 : virtual void print_converged_reason() override;
117 :
118 : /**
119 : * \returns The currently-available (or most recently obtained, if
120 : * the Tao object has been destroyed) convergence reason.
121 : *
122 : * Refer to Tao docs for the meaning of different TaoConvergedReason.
123 : */
124 : virtual int get_converged_reason() override;
125 :
126 : protected:
127 :
128 : /**
129 : * Optimization solver context
130 : */
131 : Tao _tao;
132 :
133 : /**
134 : * Store the reason for Tao convergence/divergence for use even
135 : * after \p _tao has been cleared.
136 : *
137 : * \note \p print_converged_reason() will always \e try to get the
138 : * current reason with TaoGetConvergedReason(), but if the Tao
139 : * object has already been cleared, it will fall back on this stored
140 : * value. This value is therefore necessarily \e not cleared by the
141 : * clear() function.
142 : */
143 : TaoConvergedReason _reason;
144 :
145 : private:
146 :
147 : friend PetscErrorCode __libmesh_tao_objective (Tao tao, Vec x, PetscReal * objective, void * ctx);
148 : friend PetscErrorCode __libmesh_tao_gradient(Tao tao, Vec x, Vec g, void * ctx);
149 : friend PetscErrorCode __libmesh_tao_hessian(Tao tao, Vec x, Mat h, Mat pc, void * ctx);
150 : friend PetscErrorCode __libmesh_tao_equality_constraints(Tao tao, Vec x, Vec ce, void * ctx);
151 : friend PetscErrorCode __libmesh_tao_equality_constraints_jacobian(Tao tao, Vec x, Mat J, Mat Jpre, void * ctx);
152 : friend PetscErrorCode __libmesh_tao_inequality_constraints(Tao tao, Vec x, Vec cineq, void * ctx);
153 : friend PetscErrorCode __libmesh_tao_inequality_constraints_jacobian(Tao tao, Vec x, Mat J, Mat Jpre, void * ctx);
154 : };
155 :
156 :
157 :
158 : } // namespace libMesh
159 :
160 :
161 : #endif // #if defined(LIBMESH_HAVE_PETSC_TAO) && !defined(LIBMESH_USE_COMPLEX_NUMBERS)
162 : #endif // LIBMESH_TAO_OPTIMIZATION_SOLVER_H
|