libMesh
Loading...
Searching...
No Matches
eigen_system.C
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 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#include "libmesh/libmesh_config.h"
20
21// Currently, the EigenSystem should only be available
22// if SLEPc support is enabled.
23#if defined(LIBMESH_HAVE_SLEPC)
24
25// Local includes
26#include "libmesh/eigen_system.h"
27#include "libmesh/equation_systems.h"
28#include "libmesh/sparse_matrix.h"
29#include "libmesh/shell_matrix.h"
30#include "libmesh/eigen_solver.h"
31#include "libmesh/dof_map.h"
32#include "libmesh/mesh_base.h"
33#include "libmesh/enum_eigen_solver_type.h"
34
35namespace libMesh
36{
37
38
40 const std::string & name_in,
41 const unsigned int number_in
42 ) :
43 Parent (es, name_in, number_in),
44 matrix_A (nullptr),
45 matrix_B (nullptr),
46 precond_matrix (nullptr),
47 eigen_solver (EigenSolver<Number>::build(es.comm())),
48 _n_converged_eigenpairs (0),
49 _n_iterations (0),
50 _eigen_problem_type (NHEP),
51 _use_shell_matrices (false),
52 _use_shell_precond_matrix(false)
53{
54}
55
56
57
58EigenSystem::~EigenSystem () = default;
59
60
61
63{
64 // Clear the parent data
66
67 // The SparseMatrices are contained in _matrices
68 // and are cleared with the above call
69 matrix_A = nullptr;
70 matrix_B = nullptr;
71 precond_matrix = nullptr;
72
73 // Operators
74 shell_matrix_A.reset();
75 shell_matrix_B.reset();
76
77 // Preconditioning matrices
79
80 // clear the solver
82}
83
84
86{
87 if (!can_add_matrices())
88 libmesh_error_msg("ERROR: Cannot change eigen problem type after system initialization");
89
91
92 eigen_solver->set_eigenproblem_type(ept);
93
94 // libMesh::out << "The Problem type is set to be: " << std::endl;
95
96 switch (_eigen_problem_type)
97 {
98 case HEP:
99 // libMesh::out << "Hermitian" << std::endl;
100 break;
101
102 case NHEP:
103 // libMesh::out << "Non-Hermitian" << std::endl;
104 break;
105
106 case GHEP:
107 // libMesh::out << "Generalized Hermitian" << std::endl;
108 break;
109
110 case GNHEP:
111 // libMesh::out << "Generalized Non-Hermitian" << std::endl;
112 break;
113
114 case GHIEP:
115 // libMesh::out << "Generalized indefinite Hermitian" << std::endl;
116 break;
117
118 default:
119 // libMesh::out << "not properly specified" << std::endl;
120 libmesh_error_msg("Unrecognized _eigen_problem_type = " << _eigen_problem_type);
121 }
122}
123
124
125
127{
129
131 {
132 if (!shell_matrix_A)
134
135 if (generalized() && !shell_matrix_B)
137
139 {
142 }
143 else if (!precond_matrix)
144 precond_matrix = &(this->add_matrix("Eigen Preconditioner"));
145 }
146 else
147 {
148 if (!matrix_A)
149 matrix_A = &(this->add_matrix("Eigen Matrix A"));
150
151 if (generalized() && !matrix_B)
152 matrix_B = &(this->add_matrix("Eigen Matrix B"));
153 }
154}
155
156
157
159{
161
162 const bool condense_constraints = condense_constrained_dofs();
163 if (shell_matrix_A)
164 {
165 shell_matrix_A->attach_dof_map(this->get_dof_map());
166 if (condense_constraints)
167 shell_matrix_A->omit_constrained_dofs();
168 shell_matrix_A->init();
169 }
170
171 if (shell_matrix_B)
172 {
173 shell_matrix_B->attach_dof_map(this->get_dof_map());
174 if (condense_constraints)
175 shell_matrix_B->omit_constrained_dofs();
176 shell_matrix_B->init();
177 }
178
180 {
181 shell_precond_matrix->attach_dof_map(this->get_dof_map());
182 if (condense_constraints)
183 shell_precond_matrix->omit_constrained_dofs();
184 shell_precond_matrix->init();
185 }
186}
187
188
190{
191 // initialize parent data
192 // this calls reinit on matrix_A, matrix_B, and precond_matrix (if any)
194
195 if (shell_matrix_A)
196 {
197 shell_matrix_A->clear();
198 shell_matrix_A->init();
199 }
200
201 if (shell_matrix_B)
202 {
203 shell_matrix_B->clear();
204 shell_matrix_B->init();
205 }
206
208 {
209 shell_precond_matrix->clear();
210 shell_precond_matrix->init();
211 }
212}
213
214void
216 SparseMatrix<Number> * const B,
217 SparseMatrix<Number> * const P)
218{
219 // A reference to the EquationSystems
221
222 // Get the tolerance for the solver and the maximum
223 // number of iterations. Here, we simply adopt the linear solver
224 // specific parameters.
225 const double tol = parameters.have_parameter<Real>("linear solver tolerance") ?
226 double(parameters.get<Real>("linear solver tolerance")) :
227 double(es.parameters.get<Real>("linear solver tolerance"));
228
229 const unsigned int maxits = parameters.have_parameter<unsigned int>("linear solver maximum iterations") ?
230 parameters.get<unsigned int>("linear solver maximum iterations") :
231 es.parameters.get<unsigned int>("linear solver maximum iterations");
232
233 const unsigned int nev = parameters.have_parameter<unsigned int>("eigenpairs") ?
234 parameters.get<unsigned int>("eigenpairs") :
235 es.parameters.get<unsigned int>("eigenpairs");
236
237 const unsigned int ncv = parameters.have_parameter<unsigned int>("basis vectors") ?
238 parameters.get<unsigned int>("basis vectors") :
239 es.parameters.get<unsigned int>("basis vectors");
240
241 std::pair<unsigned int, unsigned int> solve_data;
242
243 // call the solver depending on the type of eigenproblem
244
246 {
247 // Generalized eigenproblem
248 if (generalized())
249 // Shell preconditioning matrix
251 solve_data = eigen_solver->solve_generalized(
252 *shell_matrix_A, *shell_matrix_B, *shell_precond_matrix, nev, ncv, tol, maxits);
253 else
254 solve_data = eigen_solver->solve_generalized(
255 *shell_matrix_A, *shell_matrix_B, *P, nev, ncv, tol, maxits);
256
257 // Standard eigenproblem
258 else
259 {
261 // Shell preconditioning matrix
263 solve_data = eigen_solver->solve_standard(
264 *shell_matrix_A, *shell_precond_matrix, nev, ncv, tol, maxits);
265 else
266 solve_data = eigen_solver->solve_standard(*shell_matrix_A, *P, nev, ncv, tol, maxits);
267 }
268 }
269 else
270 {
271 // Generalized eigenproblem
272 if (generalized())
273 solve_data = eigen_solver->solve_generalized(*A, *B, nev, ncv, tol, maxits);
274
275 // Standard eigenproblem
276 else
277 {
279 solve_data = eigen_solver->solve_standard(*A, nev, ncv, tol, maxits);
280 }
281 }
282
283 this->_n_converged_eigenpairs = solve_data.first;
284 this->_n_iterations = solve_data.second;
285}
286
288{
290 libmesh_warning("EigenSystem does not have first-class support for constrained degrees of "
291 "freedom. You may see spurious effects of the constrained degrees of freedom "
292 "in a given eigenvector. If you wish to perform a reliable solve on a system "
293 "with constraints, please use the CondensedEigenSystem class instead");
294
295 // check that necessary parameters have been set
297 this->get_equation_systems().parameters.have_parameter<unsigned int>("eigenpairs"));
299 this->get_equation_systems().parameters.have_parameter<unsigned int>("basis vectors"));
300
301 if (this->assemble_before_solve)
302 // Assemble the linear system
303 this->assemble ();
304
306}
307
309{
310 // call the eigen_solver get_eigenpair method
311 return eigen_solver->get_eigenpair (i, *solution);
312}
313
315{
316 return eigen_solver->get_eigenvalue (i);
317}
318
320{
321 eigen_solver->set_initial_space (initial_space_in);
322}
323
324
326{
327 return _eigen_problem_type == GNHEP ||
330}
331
332
340
341
349
350
359
360
369
370
379
380
389
390
397
398
405
406
414
415
423
424
432
433
441
442
444{
445 libmesh_assert_equal_to(request_matrix("Eigen Matrix A"), matrix_A);
446 return matrix_A;
447}
448
449
451{
452 libmesh_assert_equal_to(request_matrix("Eigen Matrix B"), matrix_B);
453 return matrix_B;
454}
455
456
458{
459 libmesh_assert_equal_to(request_matrix("Eigen Preconditioner"), precond_matrix);
460 return precond_matrix;
461}
462
463
465{
466 return shell_matrix_A.get();
467}
468
469
471{
472 return shell_matrix_B.get();
473}
474
475
477{
478 return shell_precond_matrix.get();
479}
480
481
487
488
494
495
496} // namespace libMesh
497
498#endif // LIBMESH_HAVE_SLEPC
This class provides an interface to solvers for eigenvalue problems.
SparseMatrix< Number > * matrix_A
The system matrix for standard eigenvalue problems.
void set_initial_space(NumericVector< Number > &initial_space_in)
Sets an initial eigen vector.
virtual std::pair< Real, Real > get_eigenvalue(dof_id_type i)
bool _use_shell_matrices
A boolean flag to indicate whether or not to use shell matrices.
void set_eigenproblem_type(EigenProblemType ept)
Sets the type of the current eigen problem.
unsigned int _n_converged_eigenpairs
The number of converged eigenpairs.
EigenProblemType _eigen_problem_type
The type of the eigenvalue problem.
SparseMatrix< Number > * matrix_B
A second system matrix for generalized eigenvalue problems.
virtual void clear() override
Clear all the data structures associated with the system.
bool has_precond_matrix() const
bool has_matrix_A() const
std::unique_ptr< ShellMatrix< Number > > shell_matrix_A
The system shell matrix for standard eigenvalue problems.
unsigned int _n_iterations
The number of iterations of the eigen solver algorithm.
bool _use_shell_precond_matrix
A boolean flag to indicate whether or not to use a shell preconditioning matrix.
const SparseMatrix< Number > & get_matrix_B() const
virtual void solve() override
Assembles & solves the eigen system.
virtual std::pair< Real, Real > get_eigenpair(dof_id_type i)
bool generalized() const
const SparseMatrix< Number > & get_precond_matrix() const
std::unique_ptr< ShellMatrix< Number > > shell_precond_matrix
A preconditioning shell matrix.
const ShellMatrix< Number > & get_shell_matrix_A() const
const ShellMatrix< Number > & get_shell_precond_matrix() const
EigenSystem(EquationSystems &es, const std::string &name_in, const unsigned int number_in)
Constructor.
SparseMatrix< Number > * precond_matrix
A preconditioning matrix.
bool has_matrix_B() const
bool has_shell_precond_matrix() const
virtual void init_matrices() override
Initializes the matrices associated with the system.
void solve_helper(SparseMatrix< Number > *const A, SparseMatrix< Number > *const B, SparseMatrix< Number > *const P)
const ShellMatrix< Number > & get_shell_matrix_B() const
const SparseMatrix< Number > & get_matrix_A() const
std::unique_ptr< EigenSolver< Number > > eigen_solver
The EigenSolver, defining which interface, i.e solver package to use.
bool has_shell_matrix_A() const
const EigenSolver< Number > & get_eigen_solver() const
virtual void reinit() override
Reinitializes the member data fields associated with the system, so that, e.g., assemble() may be use...
virtual void add_matrices() override
Adds the necessary matrices and shell matrices.
bool has_shell_matrix_B() const
std::unique_ptr< ShellMatrix< Number > > shell_matrix_B
A second system shell matrix for generalized eigenvalue problems.
This is the EquationSystems class.
Parameters parameters
Data structure holding arbitrary parameters.
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
const Parallel::Communicator & comm() const
bool have_parameter(std::string_view) const
Definition parameters.h:420
const T & get(std::string_view) const
Definition parameters.h:451
Generic shell matrix, i.e.
static std::unique_ptr< ShellMatrix< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package())
Builds a ShellMatrix<T> using the linear solver package specified by solver_package.
Generic sparse matrix.
virtual void clear()=0
Restores the SparseMatrix<T> to a pristine state.
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition system.h:100
bool can_add_matrices() const
Definition system.h:2028
SparseMatrix< Number > & add_matrix(std::string_view mat_name, ParallelType type=PARALLEL, MatrixBuildType mat_build_type=MatrixBuildType::AUTOMATIC)
Adds the additional matrix mat_name to this system.
Definition system.C:998
virtual void reinit()
Reinitializes degrees of freedom and other required data on the current mesh.
Definition system.C:442
bool assemble_before_solve
Flag which tells the system to whether or not to call the user assembly function during each call to ...
Definition system.h:1609
virtual void assemble()
Prepares matrix and _dof_map for matrix assembly.
Definition system.C:554
dof_id_type n_constrained_dofs() const
Definition system.C:125
virtual void clear()
Clear all the data structures associated with the system.
Definition system.C:173
virtual void add_matrices()
Insertion point for adding matrices in derived classes before init_matrices() is called.
Definition system.h:2017
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition system.h:1655
virtual void init_matrices()
Initializes the matrices associated with this system.
Definition system.C:311
virtual bool condense_constrained_dofs() const
Whether this object should condense out constrained degrees of freedom.
Definition system.h:2059
Parameters parameters
Parameters for the system. If a parameter is not provided, it should be retrieved from the EquationSy...
Definition system.h:1588
const DofMap & get_dof_map() const
Definition system.h:2417
const EquationSystems & get_equation_systems() const
Definition system.h:767
const SparseMatrix< Number > * request_matrix(std::string_view mat_name) const
Definition system.C:1087
The libMesh namespace provides an interface to certain functionality in the library.
libmesh_assert(ctx)
uint8_t dof_id_type
Definition id_types.h:67
EigenProblemType
Defines an enum for eigenproblem types.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition assembly.h:39