libMesh
eigen_system.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 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 
35 namespace libMesh
36 {
37 
38 
39 // ------------------------------------------------------------
40 // EigenSystem implementation
42  const std::string & name_in,
43  const unsigned int number_in
44  ) :
45  Parent (es, name_in, number_in),
46  eigen_solver (EigenSolver<Number>::build(es.comm())),
47  _n_converged_eigenpairs (0),
48  _n_iterations (0),
49  _is_generalized_eigenproblem (false),
50  _eigen_problem_type (NHEP),
51  _use_shell_matrices (false)
52 {
53 }
54 
55 
56 
58 {
59  // clear data
60  this->clear();
61 }
62 
63 
64 
66 {
67  // Clear the parent data
68  Parent::clear();
69 
70  // Clean up the matrices
71  matrix_A.reset();
72  matrix_B.reset();
73 
74  shell_matrix_A.reset();
75  shell_matrix_B.reset();
76 
77  precond_matrix.reset();
78 
79  // clear the solver
80  eigen_solver->clear();
81 }
82 
83 
85 {
86  _eigen_problem_type = ept;
87 
88  eigen_solver->set_eigenproblem_type(ept);
89 
90  // libMesh::out << "The Problem type is set to be: " << std::endl;
91 
92  switch (_eigen_problem_type)
93  {
94  case HEP:
95  // libMesh::out << "Hermitian" << std::endl;
96  break;
97 
98  case NHEP:
99  // libMesh::out << "Non-Hermitian" << std::endl;
100  break;
101 
102  case GHEP:
103  // libMesh::out << "Generalized Hermitian" << std::endl;
104  break;
105 
106  case GNHEP:
107  // libMesh::out << "Generalized Non-Hermitian" << std::endl;
108  break;
109 
110  case GHIEP:
111  // libMesh::out << "Generalized indefinite Hermitian" << std::endl;
112  break;
113 
114  default:
115  // libMesh::out << "not properly specified" << std::endl;
116  libmesh_error_msg("Unrecognized _eigen_problem_type = " << _eigen_problem_type);
117  }
118 }
119 
120 
121 
122 
124 {
125  // initialize parent data
127 
128  // define the type of eigenproblem
129  if (_eigen_problem_type == GNHEP ||
133 
134  this->init_matrices();
135 }
136 
137 
138 
140 {
141  DofMap & dof_map = this->get_dof_map();
142 
144  {
146 
147  shell_matrix_A->attach_dof_map(dof_map);
148 
150  {
152 
153  shell_matrix_B->attach_dof_map(dof_map);
154  }
155 
157 
158  dof_map.attach_matrix(*precond_matrix);
159 
160  dof_map.compute_sparsity(this->get_mesh());
161 
162  shell_matrix_A->init();
163 
165  shell_matrix_B->init();
166 
167  precond_matrix->init();
168  precond_matrix->zero();
169  }
170  else
171  {
172  // build the system matrix
174 
175  dof_map.attach_matrix(*matrix_A);
176 
177  // build matrix_B only in case of a
178  // generalized problem
180  {
182  dof_map.attach_matrix(*matrix_B);
183  }
184 
185  dof_map.compute_sparsity(this->get_mesh());
186 
187  // initialize and zero system matrix
188  matrix_A->init();
189  matrix_A->zero();
190 
191  // eventually initialize and zero system matrix_B
193  {
194  matrix_B->init();
195  matrix_B->zero();
196  }
197  }
198 }
199 
200 
201 
203 {
204  // initialize parent data
205  Parent::reinit();
206 
207  DofMap & dof_map = this->get_dof_map();
208 
210  {
211  shell_matrix_A->clear();
212 
214  shell_matrix_B->clear();
215 
216  precond_matrix->clear();
217 
218  dof_map.clear_sparsity();
219 
220  dof_map.compute_sparsity(this->get_mesh());
221 
222  shell_matrix_A->init();
223 
225  shell_matrix_B->init();
226 
227  precond_matrix->init();
228  precond_matrix->zero();
229  }
230  else
231  {
232  // Clear the matrices
233  matrix_A->clear();
234 
236  matrix_B->clear();
237 
238  // Clear the sparsity pattern
239  dof_map.clear_sparsity();
240 
241  // Compute the sparsity pattern for the current
242  // mesh and DOF distribution. This also updates
243  // both matrices, \p DofMap now knows them
244  dof_map.compute_sparsity(this->get_mesh());
245 
246  matrix_A->init();
247  matrix_A->zero();
248 
250  {
251  matrix_B->init();
252  matrix_B->zero();
253  }
254  }
255 }
256 
257 
258 
260 {
261 
262  // A reference to the EquationSystems
263  EquationSystems & es = this->get_equation_systems();
264 
265  // check that necessary parameters have been set
266  libmesh_assert (es.parameters.have_parameter<unsigned int>("eigenpairs"));
267  libmesh_assert (es.parameters.have_parameter<unsigned int>("basis vectors"));
268 
269  if (this->assemble_before_solve)
270  // Assemble the linear system
271  this->assemble ();
272 
273  // Get the tolerance for the solver and the maximum
274  // number of iterations. Here, we simply adopt the linear solver
275  // specific parameters.
276  const Real tol =
277  es.parameters.get<Real>("linear solver tolerance");
278 
279  const unsigned int maxits =
280  es.parameters.get<unsigned int>("linear solver maximum iterations");
281 
282  const unsigned int nev =
283  es.parameters.get<unsigned int>("eigenpairs");
284 
285  const unsigned int ncv =
286  es.parameters.get<unsigned int>("basis vectors");
287 
288  std::pair<unsigned int, unsigned int> solve_data;
289 
290  // call the solver depending on the type of eigenproblem
291 
293  {
294  // Generalized eigenproblem
296  solve_data = eigen_solver->solve_generalized (*shell_matrix_A, *shell_matrix_B,*precond_matrix, nev, ncv, tol, maxits);
297 
298  // Standard eigenproblem
299  else
300  {
302  solve_data = eigen_solver->solve_standard (*shell_matrix_A,*precond_matrix, nev, ncv, tol, maxits);
303  }
304  }
305  else
306  {
307  // Generalized eigenproblem
309  solve_data = eigen_solver->solve_generalized (*matrix_A, *matrix_B, nev, ncv, tol, maxits);
310 
311  // Standard eigenproblem
312  else
313  {
315  solve_data = eigen_solver->solve_standard (*matrix_A, nev, ncv, tol, maxits);
316  }
317  }
318 
319  this->_n_converged_eigenpairs = solve_data.first;
320  this->_n_iterations = solve_data.second;
321 }
322 
323 
325 {
326 
327  // Assemble the linear system
328  Parent::assemble ();
329 
330 }
331 
332 
333 std::pair<Real, Real> EigenSystem::get_eigenpair (dof_id_type i)
334 {
335  // call the eigen_solver get_eigenpair method
336  return eigen_solver->get_eigenpair (i, *solution);
337 }
338 
339 } // namespace libMesh
340 
341 #endif // LIBMESH_HAVE_SLEPC
libMesh::System
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:100
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::Number
Real Number
Definition: libmesh_common.h:195
libMesh::DofMap::compute_sparsity
void compute_sparsity(const MeshBase &)
Computes the sparsity pattern for the matrices corresponding to proc_id and sends that data to Linear...
Definition: dof_map.C:1768
libMesh::System::get_equation_systems
const EquationSystems & get_equation_systems() const
Definition: system.h:720
libMesh::System::reinit
virtual void reinit()
Reinitializes degrees of freedom and other required data on the current mesh.
Definition: system.C:390
libMesh::EigenSystem::matrix_A
std::unique_ptr< SparseMatrix< Number > > matrix_A
The system matrix for standard eigenvalue problems.
Definition: eigen_system.h:165
libMesh::EigenSystem::_is_generalized_eigenproblem
bool _is_generalized_eigenproblem
A boolean flag to indicate whether we are dealing with a generalized eigenvalue problem.
Definition: eigen_system.h:239
libMesh::EigenSystem::shell_matrix_B
std::unique_ptr< ShellMatrix< Number > > shell_matrix_B
A second system shell matrix for generalized eigenvalue problems.
Definition: eigen_system.h:180
libMesh::GHIEP
Definition: enum_eigen_solver_type.h:59
libMesh::HEP
Definition: enum_eigen_solver_type.h:56
libMesh::EigenProblemType
EigenProblemType
Defines an enum for eigenproblem types.
Definition: enum_eigen_solver_type.h:54
libMesh::EigenSystem::init_matrices
virtual void init_matrices()
Initializes the matrices associated with the system.
Definition: eigen_system.C:139
libMesh::EigenSystem::~EigenSystem
virtual ~EigenSystem()
Destructor.
Definition: eigen_system.C:57
libMesh::EigenSystem::solve
virtual void solve() override
Assembles & solves the eigen system.
Definition: eigen_system.C:259
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::EigenSystem::EigenSystem
EigenSystem(EquationSystems &es, const std::string &name_in, const unsigned int number_in)
Constructor.
Definition: eigen_system.C:41
libMesh::ParallelObject::comm
const Parallel::Communicator & comm() const
Definition: parallel_object.h:94
libMesh::EigenSystem::eigen_solver
std::unique_ptr< EigenSolver< Number > > eigen_solver
The EigenSolver, defining which interface, i.e solver package to use.
Definition: eigen_system.h:191
libMesh::EigenSystem::set_eigenproblem_type
void set_eigenproblem_type(EigenProblemType ept)
Sets the type of the current eigen problem.
Definition: eigen_system.C:84
libMesh::EigenSystem::clear
virtual void clear() override
Clear all the data structures associated with the system.
Definition: eigen_system.C:65
libMesh::EigenSystem::_eigen_problem_type
EigenProblemType _eigen_problem_type
The type of the eigenvalue problem.
Definition: eigen_system.h:244
libMesh::EigenSystem::_use_shell_matrices
bool _use_shell_matrices
A boolean flag to indicate whether or not to use shell matrices.
Definition: eigen_system.h:249
libMesh::System::assemble
virtual void assemble()
Prepares matrix and _dof_map for matrix assembly.
Definition: system.C:462
libMesh::EigenSystem::precond_matrix
std::unique_ptr< SparseMatrix< Number > > precond_matrix
A preconditioning matrix.
Definition: eigen_system.h:185
libMesh::Parameters::have_parameter
bool have_parameter(const std::string &) const
Definition: parameters.h:402
libMesh::EigenSystem::matrix_B
std::unique_ptr< SparseMatrix< Number > > matrix_B
A second system matrix for generalized eigenvalue problems.
Definition: eigen_system.h:170
libMesh::System::assemble_before_solve
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:1493
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::EigenSystem::init_data
virtual void init_data() override
Initializes the member data fields associated with the system, so that, e.g., assemble() may be used.
Definition: eigen_system.C:123
libMesh::System::get_mesh
const MeshBase & get_mesh() const
Definition: system.h:2083
libMesh::EigenSystem::get_eigenpair
virtual std::pair< Real, Real > get_eigenpair(dof_id_type i)
Definition: eigen_system.C:333
libMesh::EigenSystem::reinit
virtual void reinit() override
Reinitializes the member data fields associated with the system, so that, e.g., assemble() may be use...
Definition: eigen_system.C:202
libMesh::EquationSystems
This is the EquationSystems class.
Definition: equation_systems.h:74
libMesh::DofMap::attach_matrix
void attach_matrix(SparseMatrix< Number > &matrix)
Additional matrices may be handled with this DofMap.
Definition: dof_map.C:274
libMesh::System::solution
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1539
libMesh::NHEP
Definition: enum_eigen_solver_type.h:55
libMesh::SparseMatrix::build
static std::unique_ptr< SparseMatrix< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package())
Builds a SparseMatrix<T> using the linear solver package specified by solver_package.
Definition: sparse_matrix.C:130
libMesh::DofMap
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:176
libMesh::DofMap::clear_sparsity
void clear_sparsity()
Clears the sparsity pattern.
Definition: dof_map.C:1800
libMesh::ShellMatrix::build
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.
Definition: shell_matrix.C:33
libMesh::EigenSystem::_n_converged_eigenpairs
unsigned int _n_converged_eigenpairs
The number of converged eigenpairs.
Definition: eigen_system.h:228
libMesh::System::init_data
virtual void init_data()
Initializes the data for the system.
Definition: system.C:262
libMesh::GHEP
Definition: enum_eigen_solver_type.h:58
libMesh::EigenSolver
This class provides an interface to solvers for eigenvalue problems.
Definition: eigen_solver.h:67
libMesh::System::clear
virtual void clear()
Clear all the data structures associated with the system.
Definition: system.C:205
libMesh::EigenSystem::shell_matrix_A
std::unique_ptr< ShellMatrix< Number > > shell_matrix_A
The system shell matrix for standard eigenvalue problems.
Definition: eigen_system.h:175
libMesh::EigenSystem::_n_iterations
unsigned int _n_iterations
The number of iterations of the eigen solver algorithm.
Definition: eigen_system.h:233
libMesh::System::get_dof_map
const DofMap & get_dof_map() const
Definition: system.h:2099
libMesh::GNHEP
Definition: enum_eigen_solver_type.h:57
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::Parameters::get
const T & get(const std::string &) const
Definition: parameters.h:421
libMesh::EigenSystem::assemble
virtual void assemble() override
Assembles the system matrix.
Definition: eigen_system.C:324
libMesh::EquationSystems::parameters
Parameters parameters
Data structure holding arbitrary parameters.
Definition: equation_systems.h:557