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