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 : #ifndef LIBMESH_EIGEN_SYSTEM_H 20 : #define LIBMESH_EIGEN_SYSTEM_H 21 : 22 : #include "libmesh/libmesh_config.h" 23 : 24 : // Currently, the EigenSystem should only be available 25 : // if SLEPc support is enabled. 26 : #if defined(LIBMESH_HAVE_SLEPC) 27 : 28 : // Local Includes 29 : #include "libmesh/system.h" 30 : #include "libmesh/eigen_solver.h" 31 : 32 : namespace libMesh 33 : { 34 : 35 : // Forward Declarations 36 : template <typename T> class SparseMatrix; 37 : template <typename T> class ShellMatrix; 38 : 39 : 40 : /** 41 : * \brief Manages consistently variables, degrees of freedom, and coefficient 42 : * vectors for eigenvalue problems. 43 : * 44 : * Currently, this class is able to handle standard eigenvalue 45 : * problems \p A*x=lambda*x and generalized eigenvalue problems \p 46 : * A*x=lambda*B*x. 47 : * 48 : * The matrices EigenSystem::matrix_A and EigenSystem::matrix_B should be 49 : * filled during assembly. 50 : * 51 : * \author Steffen Peterson 52 : * \date 2005 53 : * \brief Base class for defining systems of equations for eigenproblems. 54 : */ 55 32 : class EigenSystem : public System 56 : { 57 : public: 58 : 59 : /** 60 : * Constructor. 61 : */ 62 : EigenSystem (EquationSystems & es, 63 : const std::string & name_in, 64 : const unsigned int number_in); 65 : 66 : /** 67 : * Special functions. 68 : * - This class has the same restrictions/defaults as its base class. 69 : * - Destructor is defaulted out-of-line 70 : */ 71 : EigenSystem (const EigenSystem &) = delete; 72 : EigenSystem & operator= (const EigenSystem &) = delete; 73 : EigenSystem (EigenSystem &&) = default; 74 : EigenSystem & operator= (EigenSystem &&) = delete; 75 : virtual ~EigenSystem (); 76 : 77 : /** 78 : * The type of system. 79 : */ 80 : typedef EigenSystem sys_type; 81 : 82 : /** 83 : * The type of the parent 84 : */ 85 : typedef System Parent; 86 : 87 : /** 88 : * \returns A reference to *this. 89 : */ 90 : sys_type & system () { return *this; } 91 : 92 : /** 93 : * Clear all the data structures associated with 94 : * the system. 95 : */ 96 : virtual void clear () override; 97 : 98 : /** 99 : * Reinitializes the member data fields associated with 100 : * the system, so that, e.g., \p assemble() may be used. 101 : */ 102 : virtual void reinit () override; 103 : 104 : /** 105 : * Assembles & solves the eigen system. 106 : */ 107 : virtual void solve () override; 108 : 109 : /** 110 : * \returns Real and imaginary part of the ith eigenvalue and copies 111 : * the respective eigen vector to the solution vector. 112 : */ 113 : virtual std::pair<Real, Real> get_eigenpair (dof_id_type i); 114 : 115 : /** 116 : * \returns Real and imaginary part of the ith eigenvalue but 117 : * does not copy the respective eigen vector to the solution vector. 118 : */ 119 : virtual std::pair<Real, Real> get_eigenvalue (dof_id_type i); 120 : 121 : /** 122 : * \returns \p "Eigen". Helps in identifying 123 : * the system type in an equation system file. 124 : */ 125 348 : virtual std::string system_type () const override { return "Eigen"; } 126 : 127 : /** 128 : * \returns The number of converged eigenpairs. 129 : */ 130 13 : unsigned int get_n_converged () const {return _n_converged_eigenpairs;} 131 : 132 : /** 133 : * \returns The number of eigen solver iterations. 134 : */ 135 : unsigned int get_n_iterations () const {return _n_iterations;} 136 : 137 : /** 138 : * Sets the type of the current eigen problem. 139 : */ 140 : void set_eigenproblem_type (EigenProblemType ept); 141 : 142 : /** 143 : * \returns The eigen problem type. 144 : */ 145 : EigenProblemType get_eigenproblem_type () const {return _eigen_problem_type;} 146 : 147 : /** 148 : * Sets an initial eigen vector 149 : */ 150 : void set_initial_space(NumericVector<Number> & initial_space_in); 151 : 152 : /** 153 : * \returns \p true if the underlying problem is generalized 154 : * , false otherwise. 155 : */ 156 : bool generalized () const; 157 : 158 : /** 159 : * \returns \p true if the shell matrices are used 160 : */ 161 204 : bool use_shell_matrices() const { return _use_shell_matrices; } 162 : 163 : /** 164 : * Set a flag to use shell matrices 165 : */ 166 : void use_shell_matrices(bool use_shell_matrices) { _use_shell_matrices = use_shell_matrices; } 167 : 168 : /** 169 : * \returns \p true if a shell preconditioning matrix is used 170 : */ 171 66 : bool use_shell_precond_matrix() const { return _use_shell_precond_matrix; } 172 : 173 : /** 174 : * Set a flag to use a shell preconditioning matrix 175 : */ 176 : void use_shell_precond_matrix(bool use_shell_precond_matrix) { _use_shell_precond_matrix = use_shell_precond_matrix; } 177 : 178 : /** 179 : * \returns A const reference to the system matrix used for standard eigenvalue problems. 180 : * 181 : * This matrix should only be available (and therefore this should only be called) 182 : * if !_use_shell_matrices. 183 : */ 184 : const SparseMatrix<Number> & get_matrix_A() const; 185 : 186 : /** 187 : * \returns A reference to the system matrix used for standard eigenvalue problems. 188 : * 189 : * This matrix should only be available (and therefore this should only be called) 190 : * if !_use_shell_matrices. 191 : */ 192 : SparseMatrix<Number> & get_matrix_A(); 193 : 194 : /** 195 : * \returns A const reference to the system matrix used for generalized eigenvalue problems 196 : * 197 : * This matrix should only be available (and therefore this should only be called) 198 : * if !_use_shell_matrices and generalized(). 199 : */ 200 : const SparseMatrix<Number> & get_matrix_B() const; 201 : 202 : /** 203 : * \returns A const reference to the system matrix used for generalized eigenvalue problems 204 : * 205 : * This matrix should only be available (and therefore this should only be called) 206 : * if !_use_shell_matrices and generalized(). 207 : */ 208 : SparseMatrix<Number> & get_matrix_B(); 209 : 210 : /** 211 : * \returns A const reference to the preconditioning matrix. 212 : * 213 : * This matrix should only be available (and therefore this should only be called) 214 : * if !_use_shell_matrices. 215 : */ 216 : const SparseMatrix<Number> & get_precond_matrix() const; 217 : 218 : /** 219 : * \returns A reference to the preconditioning matrix. 220 : * 221 : * This matrix should only be available (and therefore this should only be called) 222 : * if !_use_shell_matrices. 223 : */ 224 : SparseMatrix<Number> & get_precond_matrix(); 225 : 226 : /** 227 : * \returns A const reference to the system shell matrix used for standard eigenvalue problems. 228 : * 229 : * This matrix should only be available (and therefore this should only be called) 230 : * if _use_shell_matrices. 231 : */ 232 : const ShellMatrix<Number> & get_shell_matrix_A() const; 233 : 234 : /** 235 : * \returns A reference to the system shell matrix used for standard eigenvalue problems. 236 : * 237 : * This matrix should only be available (and therefore this should only be called) 238 : * if _use_shell_matrices. 239 : */ 240 : ShellMatrix<Number> & get_shell_matrix_A(); 241 : 242 : /** 243 : * \returns A const reference to the system shell matrix used for generalized eigenvalue problems. 244 : * 245 : * This matrix should only be available (and therefore this should only be called) 246 : * if _use_shell_matrices and generalized(). 247 : */ 248 : const ShellMatrix<Number> & get_shell_matrix_B() const; 249 : 250 : /** 251 : * \returns A reference to the system shell matrix used for generalized eigenvalue problems. 252 : * 253 : * This matrix should only be available (and therefore this should only be called) 254 : * if _use_shell_matrices and generalized(). 255 : */ 256 : ShellMatrix<Number> & get_shell_matrix_B(); 257 : 258 : /** 259 : * \returns A const reference to the system shell matrix used for preconditioning. 260 : */ 261 : const ShellMatrix<Number> & get_shell_precond_matrix() const; 262 : 263 : /** 264 : * \returns A reference to the system shell matrix used for preconditioning. 265 : */ 266 : ShellMatrix<Number> & get_shell_precond_matrix(); 267 : 268 : /** 269 : * \returns A const reference to the EigenSolver. 270 : */ 271 : const EigenSolver<Number> & get_eigen_solver() const; 272 : /** 273 : * \returns A reference to the EigenSolver. 274 : */ 275 : EigenSolver<Number> & get_eigen_solver(); 276 : 277 : /** 278 : * \returns Whether or not the system has matrix A 279 : */ 280 : bool has_matrix_A() const; 281 : 282 : /** 283 : * \returns Whether or not the system has matrix B 284 : */ 285 : bool has_matrix_B() const; 286 : 287 : /** 288 : * \returns Whether or not the system has the non-shell preconditioning matrix 289 : */ 290 : bool has_precond_matrix() const; 291 : 292 : /** 293 : * \returns Whether or not the system has the shell matrix A 294 : */ 295 : bool has_shell_matrix_A() const; 296 : 297 : /** 298 : * \returns Whether or not the system has the shell matrix B 299 : */ 300 : bool has_shell_matrix_B() const; 301 : 302 : /** 303 : * \returns Whether or not the system has the shell preconditioning matrix 304 : */ 305 : bool has_shell_precond_matrix() const; 306 : 307 : /** 308 : * The system matrix for standard eigenvalue problems. 309 : * 310 : * Public access to this member variable will be deprecated in 311 : * the future! Use get_matrix_A() instead. 312 : */ 313 : SparseMatrix<Number> * matrix_A; 314 : 315 : /** 316 : * A second system matrix for generalized eigenvalue problems. 317 : * 318 : * Public access to this member variable will be deprecated in 319 : * the future! Use get_matrix_B() instead. 320 : */ 321 : SparseMatrix<Number> * matrix_B; 322 : 323 : /** 324 : * The system shell matrix for standard eigenvalue problems. 325 : * 326 : * Public access to this member variable will be deprecated in 327 : * the future! Use get_shell_matrix_A() instead. 328 : */ 329 : std::unique_ptr<ShellMatrix<Number>> shell_matrix_A; 330 : 331 : /** 332 : * A second system shell matrix for generalized eigenvalue problems. 333 : * 334 : * Public access to this member variable will be deprecated in 335 : * the future! Use get_shell_matrix_B() instead. 336 : */ 337 : std::unique_ptr<ShellMatrix<Number>> shell_matrix_B; 338 : 339 : /** 340 : * A preconditioning matrix 341 : * 342 : * Public access to this member variable will be deprecated in 343 : * the future! Use get_precond_matrix() instead. 344 : */ 345 : SparseMatrix<Number> * precond_matrix; 346 : 347 : /** 348 : * A preconditioning shell matrix 349 : * 350 : * Public access to this member variable will be deprecated in 351 : * the future! Use get_shell_precond_matrix() instead. 352 : */ 353 : std::unique_ptr<ShellMatrix<Number>> shell_precond_matrix; 354 : 355 : /** 356 : * The EigenSolver, defining which interface, i.e solver 357 : * package to use. 358 : * 359 : * Public access to this member variable will be deprecated in 360 : * the future! Use get_eigen_solver instead. 361 : */ 362 : std::unique_ptr<EigenSolver<Number>> eigen_solver; 363 : 364 : 365 : protected: 366 : 367 : /** 368 : * Adds the necessary matrices and shell matrices 369 : */ 370 : virtual void add_matrices () override; 371 : 372 : /** 373 : * Initializes the matrices associated with the system 374 : */ 375 : virtual void init_matrices () override; 376 : 377 : /** 378 : * Set the _n_converged_eigenpairs member, useful for 379 : * subclasses of EigenSystem. 380 : */ 381 : void set_n_converged (unsigned int nconv) 382 : { _n_converged_eigenpairs = nconv; } 383 : 384 : /** 385 : * Set the _n_iterations member, useful for subclasses of 386 : * EigenSystem. 387 : */ 388 : void set_n_iterations (unsigned int its) 389 : { _n_iterations = its;} 390 : 391 : void solve_helper(SparseMatrix<Number> * const A, 392 : SparseMatrix<Number> * const B, 393 : SparseMatrix<Number> * const P); 394 : 395 : private: 396 : /** 397 : * The number of converged eigenpairs. 398 : */ 399 : unsigned int _n_converged_eigenpairs; 400 : 401 : /** 402 : * The number of iterations of the eigen solver algorithm. 403 : */ 404 : unsigned int _n_iterations; 405 : 406 : /** 407 : * The type of the eigenvalue problem. 408 : */ 409 : EigenProblemType _eigen_problem_type; 410 : 411 : /** 412 : * A boolean flag to indicate whether or not to use shell matrices 413 : */ 414 : bool _use_shell_matrices; 415 : 416 : /** 417 : * A boolean flag to indicate whether or not to use a shell preconditioning matrix 418 : */ 419 : bool _use_shell_precond_matrix; 420 : }; 421 : 422 : } // namespace libMesh 423 : 424 : #endif // LIBMESH_HAVE_SLEPC 425 : 426 : #endif // LIBMESH_EIGEN_SYSTEM_H