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_OPTIMIZATION_SOLVER_H 21 : #define LIBMESH_OPTIMIZATION_SOLVER_H 22 : 23 : // Local includes 24 : #include "libmesh/libmesh_common.h" 25 : #include "libmesh/reference_counted_object.h" 26 : #include "libmesh/libmesh.h" 27 : #include "libmesh/parallel_object.h" 28 : #include "libmesh/optimization_system.h" 29 : 30 : // C++ includes 31 : #include <cstddef> 32 : #include <memory> 33 : 34 : namespace libMesh 35 : { 36 : 37 : // forward declarations 38 : template <typename T> class SparseMatrix; 39 : template <typename T> class NumericVector; 40 : template <typename T> class Preconditioner; 41 : enum SolverPackage : int; 42 : 43 : /** 44 : * This base class can be inherited from to provide interfaces to 45 : * optimization solvers from different packages like PETSc/TAO and 46 : * nlopt. 47 : * 48 : * \author David Knezevic 49 : * \date 2015 50 : */ 51 : template <typename T> 52 8 : class OptimizationSolver : public ReferenceCountedObject<OptimizationSolver<T>>, 53 : public ParallelObject 54 : { 55 : public: 56 : /** 57 : * The type of system 58 : */ 59 : typedef OptimizationSystem sys_type; 60 : 61 : /** 62 : * Constructor. Initializes Solver data structures 63 : */ 64 : explicit 65 : OptimizationSolver (sys_type & s); 66 : 67 : /** 68 : * Destructor. 69 : */ 70 : virtual ~OptimizationSolver (); 71 : 72 : /** 73 : * Builds an \p OptimizationSolver using the package specified by 74 : * \p solver_package 75 : */ 76 : static std::unique_ptr<OptimizationSolver<T>> build(sys_type & s, 77 : const SolverPackage solver_package = libMesh::default_solver_package()); 78 : 79 : /** 80 : * \returns \p true if the data structures are 81 : * initialized, false otherwise. 82 : */ 83 415 : bool initialized () const { return _is_initialized; } 84 : 85 : /** 86 : * Release all memory and clear data structures. 87 : */ 88 0 : virtual void clear () {} 89 : 90 : /** 91 : * Initialize data structures if not done so already. 92 : */ 93 : virtual void init () = 0; 94 : 95 : /** 96 : * Solves the optimization problem. 97 : */ 98 : virtual void solve () = 0; 99 : 100 : /** 101 : * Get the current values of dual variables associated with 102 : * inequality and equality constraints. The variables will 103 : * be stored in _system.lambda_eq and _system.lambda_ineq. 104 : */ 105 0 : virtual void get_dual_variables() 106 0 : { libmesh_not_implemented(); } 107 : 108 : /** 109 : * Prints a useful message about why the latest optimization solve 110 : * con(di)verged. 111 : */ 112 0 : virtual void print_converged_reason() { libmesh_not_implemented(); } 113 : 114 : /** 115 : * \returns 0, but derived classes should override this to return an 116 : * appropriate integer convergence status value. 117 : * 118 : * Most optimization solver packages return an integer status 119 : * result of some kind. This interface assumes they can be coerced 120 : * into an "int" type, which is usually safe since they are based on 121 : * enumerations. 122 : */ 123 0 : virtual int get_converged_reason() { return 0; } 124 : 125 : /** 126 : * Object that computes the objective function f(X) 127 : * at the input iterate X. 128 : */ 129 : OptimizationSystem::ComputeObjective * objective_object; 130 : 131 : /** 132 : * Object that computes the gradient grad_f(X) of the objective function 133 : * at the input iterate X. 134 : */ 135 : OptimizationSystem::ComputeGradient * gradient_object; 136 : 137 : /** 138 : * Object that computes the Hessian H_f(X) of the objective function 139 : * at the input iterate X. 140 : */ 141 : OptimizationSystem::ComputeHessian * hessian_object; 142 : 143 : /** 144 : * Object that computes the equality constraints vector C_eq(X). 145 : * This will lead to the constraints C_eq(X) = 0 being imposed. 146 : */ 147 : OptimizationSystem::ComputeEqualityConstraints * equality_constraints_object; 148 : 149 : /** 150 : * Object that computes the Jacobian of C_eq(X). 151 : */ 152 : OptimizationSystem::ComputeEqualityConstraintsJacobian * equality_constraints_jacobian_object; 153 : 154 : /** 155 : * Object that computes the inequality constraints vector C_ineq(X). 156 : * This will lead to the constraints C_ineq(X) >= 0 being imposed. 157 : */ 158 : OptimizationSystem::ComputeInequalityConstraints * inequality_constraints_object; 159 : 160 : /** 161 : * Object that computes the Jacobian of C_ineq(X). 162 : */ 163 : OptimizationSystem::ComputeInequalityConstraintsJacobian * inequality_constraints_jacobian_object; 164 : 165 : /** 166 : * Object that computes the lower and upper bounds vectors. 167 : */ 168 : OptimizationSystem::ComputeLowerAndUpperBounds * lower_and_upper_bounds_object; 169 : 170 : /** 171 : * \returns A constant reference to the system we are using to 172 : * define the optimization problem. 173 : */ 174 0 : const sys_type & system () const { return _system; } 175 : 176 : /** 177 : * \returns A writable reference to the system we are using to 178 : * define the optimization problem. 179 : */ 180 2912 : sys_type & system () { return _system; } 181 : 182 : /** 183 : * Maximum number of objective function evaluations allowed. 184 : */ 185 : unsigned int max_objective_function_evaluations; 186 : 187 : /** 188 : * Required change in objective function which signals convergence. 189 : */ 190 : double objective_function_relative_tolerance; 191 : 192 : /** 193 : * Control how much is output from the OptimizationSolver as it's running. 194 : */ 195 : bool verbose; 196 : 197 : protected: 198 : 199 : /** 200 : * A reference to the system we are solving. 201 : */ 202 : sys_type & _system; 203 : 204 : /** 205 : * Flag indicating if the data structures have been initialized. 206 : */ 207 : bool _is_initialized; 208 : 209 : }; 210 : 211 : } // namespace libMesh 212 : 213 : 214 : #endif // LIBMESH_OPTIMIZATION_SOLVER_H