libMesh
condensed_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 #include "libmesh/libmesh_config.h"
19 
20 // Currently, the EigenSystem should only be available
21 // if SLEPc support is enabled.
22 #if defined(LIBMESH_HAVE_SLEPC)
23 
24 #include "libmesh/condensed_eigen_system.h"
25 
26 #include "libmesh/dof_map.h"
27 #include "libmesh/equation_systems.h"
28 #include "libmesh/int_range.h"
29 #include "libmesh/libmesh_logging.h"
30 #include "libmesh/numeric_vector.h"
31 #include "libmesh/parallel.h"
32 
33 namespace libMesh
34 {
35 
37  const std::string & name_in,
38  const unsigned int number_in)
39  : Parent(es, name_in, number_in),
40  condensed_matrix_A(SparseMatrix<Number>::build(es.comm())),
41  condensed_matrix_B(SparseMatrix<Number>::build(es.comm())),
42  condensed_dofs_initialized(false)
43 {
44 }
45 
46 void
47 CondensedEigenSystem::initialize_condensed_dofs(const std::set<dof_id_type> & global_dirichlet_dofs_set)
48 {
49  const DofMap & dof_map = this->get_dof_map();
50 
51  // First, put all unconstrained local dofs into non_dirichlet_dofs_set
52  std::set<dof_id_type> local_non_condensed_dofs_set;
53  for (auto i : IntRange<dof_id_type>(dof_map.first_dof(),
54  dof_map.end_dof()))
55 #if LIBMESH_ENABLE_CONSTRAINTS
56  if (!dof_map.is_constrained_dof(i))
57 #endif
58  local_non_condensed_dofs_set.insert(i);
59 
60  // Now erase the condensed dofs
61  for (const auto & dof : global_dirichlet_dofs_set)
62  if ((dof_map.first_dof() <= dof) && (dof < dof_map.end_dof()))
63  local_non_condensed_dofs_set.erase(dof);
64 
65  // Finally, move local_non_condensed_dofs_set over to a vector for convenience in solve()
66  this->local_non_condensed_dofs_vector.clear();
67 
68  for (const auto & dof : local_non_condensed_dofs_set)
69  this->local_non_condensed_dofs_vector.push_back(dof);
70 
72 }
73 
75 {
77  {
78  return this->n_dofs();
79  }
80  else
81  {
83  cast_int<dof_id_type>(local_non_condensed_dofs_vector.size());
84  this->comm().sum(n_global_non_condensed_dofs);
85 
87  }
88 }
89 
90 
92 {
93  LOG_SCOPE("solve()", "CondensedEigenSystem");
94 
95  // If we haven't initialized any condensed dofs,
96  // just use the default eigen_system
98  {
99  Parent::solve();
100  return;
101  }
102 
103  // A reference to the EquationSystems
104  EquationSystems & es = this->get_equation_systems();
105 
106  // check that necessary parameters have been set
107  libmesh_assert (es.parameters.have_parameter<unsigned int>("eigenpairs"));
108  libmesh_assert (es.parameters.have_parameter<unsigned int>("basis vectors"));
109 
110  if (this->assemble_before_solve)
111  {
112  // Assemble the linear system
113  this->assemble ();
114 
115  // And close the assembled matrices; using a non-closed matrix
116  // with create_submatrix() is deprecated.
117  matrix_A->close();
118  if (generalized())
119  matrix_B->close();
120  }
121 
122  // If we reach here, then there should be some non-condensed dofs
124 
125  // Now condense the matrices
126  matrix_A->create_submatrix(*condensed_matrix_A,
129 
130  if (generalized())
131  {
132  matrix_B->create_submatrix(*condensed_matrix_B,
135  }
136 
137 
138  // Get the tolerance for the solver and the maximum
139  // number of iterations. Here, we simply adopt the linear solver
140  // specific parameters.
141  const Real tol =
142  es.parameters.get<Real>("linear solver tolerance");
143 
144  const unsigned int maxits =
145  es.parameters.get<unsigned int>("linear solver maximum iterations");
146 
147  const unsigned int nev =
148  es.parameters.get<unsigned int>("eigenpairs");
149 
150  const unsigned int ncv =
151  es.parameters.get<unsigned int>("basis vectors");
152 
153  std::pair<unsigned int, unsigned int> solve_data;
154 
155  // call the solver depending on the type of eigenproblem
156  if (generalized())
157  {
158  //in case of a generalized eigenproblem
159  solve_data = eigen_solver->solve_generalized
160  (*condensed_matrix_A,*condensed_matrix_B, nev, ncv, tol, maxits);
161  }
162 
163  else
164  {
166 
167  //in case of a standard eigenproblem
168  solve_data = eigen_solver->solve_standard (*condensed_matrix_A, nev, ncv, tol, maxits);
169  }
170 
171  set_n_converged(solve_data.first);
172  set_n_iterations(solve_data.second);
173 }
174 
175 
176 
178 {
179  LOG_SCOPE("get_eigenpair()", "CondensedEigenSystem");
180 
181  // If we haven't initialized any condensed dofs,
182  // just use the default eigen_system
184  return Parent::get_eigenpair(i);
185 
186  // If we reach here, then there should be some non-condensed dofs
188 
189  // This function assumes that condensed_solve has just been called.
190  // If this is not the case, then we will trip an asset in get_eigenpair
191  std::unique_ptr<NumericVector<Number>> temp = NumericVector<Number>::build(this->comm());
192  const dof_id_type n_local =
193  cast_int<dof_id_type>(local_non_condensed_dofs_vector.size());
194  dof_id_type n = n_local;
195  this->comm().sum(n);
196 
197  temp->init (n, n_local, false, PARALLEL);
198 
199  std::pair<Real, Real> eval = eigen_solver->get_eigenpair (i, *temp);
200 
201  // Now map temp to solution. Loop over local entries of local_non_condensed_dofs_vector
202  this->solution->zero();
203  for (auto j : IntRange<dof_id_type>(0, n_local))
204  {
206  solution->set(index,(*temp)(temp->first_local_index()+j));
207  }
208 
209  solution->close();
210  this->update();
211 
212  return eval;
213 }
214 
215 
216 
217 
218 } // namespace libMesh
219 
220 
221 #endif // LIBMESH_HAVE_SLEPC
libMesh::CondensedEigenSystem::condensed_matrix_B
std::unique_ptr< SparseMatrix< Number > > condensed_matrix_B
A second (condensed) system matrix for generalized eigenvalue problems.
Definition: condensed_eigen_system.h:117
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::Number
Real Number
Definition: libmesh_common.h:195
libMesh::EigenSystem::set_n_converged
void set_n_converged(unsigned int nconv)
Set the _n_converged_eigenpairs member, useful for subclasses of EigenSystem.
Definition: eigen_system.h:212
libMesh::System::get_equation_systems
const EquationSystems & get_equation_systems() const
Definition: system.h:720
libMesh::EigenSystem::matrix_A
std::unique_ptr< SparseMatrix< Number > > matrix_A
The system matrix for standard eigenvalue problems.
Definition: eigen_system.h:165
libMesh::PARALLEL
Definition: enum_parallel_type.h:36
libMesh::CondensedEigenSystem::solve
virtual void solve() override
Override to solve the condensed eigenproblem with the dofs in local_non_condensed_dofs_vector strippe...
Definition: condensed_eigen_system.C:91
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::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::CondensedEigenSystem::get_eigenpair
virtual std::pair< Real, Real > get_eigenpair(dof_id_type i) override
Override get_eigenpair() to retrieve the eigenpair for the condensed eigensolve.
Definition: condensed_eigen_system.C:177
libMesh::DofMap::first_dof
dof_id_type first_dof(const processor_id_type proc) const
Definition: dof_map.h:650
libMesh::DofMap::is_constrained_dof
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:1962
libMesh::SparseMatrix
Generic sparse matrix.
Definition: vector_fe_ex5.C:45
libMesh::NumericVector::build
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package())
Builds a NumericVector on the processors in communicator comm using the linear solver package specifi...
Definition: numeric_vector.C:49
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::EigenSystem::generalized
bool generalized() const
Definition: eigen_system.h:150
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::IntRange
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition: int_range.h:53
libMesh::CondensedEigenSystem::CondensedEigenSystem
CondensedEigenSystem(EquationSystems &es, const std::string &name_in, const unsigned int number_in)
Constructor.
Definition: condensed_eigen_system.C:36
libMesh::EigenSystem::get_eigenpair
virtual std::pair< Real, Real > get_eigenpair(dof_id_type i)
Definition: eigen_system.C:333
libMesh::CondensedEigenSystem::initialize_condensed_dofs
void initialize_condensed_dofs(const std::set< dof_id_type > &global_condensed_dofs_set=std::set< dof_id_type >())
Loop over the dofs on each processor to initialize the list of non-condensed dofs.
Definition: condensed_eigen_system.C:47
libMesh::EquationSystems
This is the EquationSystems class.
Definition: equation_systems.h:74
libMesh::CondensedEigenSystem::local_non_condensed_dofs_vector
std::vector< dof_id_type > local_non_condensed_dofs_vector
Vector storing the local dof indices that will not be condensed.
Definition: condensed_eigen_system.h:124
libMesh::System::solution
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1539
libMesh::EigenSystem
Manages consistently variables, degrees of freedom, and coefficient vectors for eigenvalue problems.
Definition: eigen_system.h:55
libMesh::DofMap
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:176
libMesh::CondensedEigenSystem::condensed_matrix_A
std::unique_ptr< SparseMatrix< Number > > condensed_matrix_A
The (condensed) system matrix for standard eigenvalue problems.
Definition: condensed_eigen_system.h:112
libMesh::System::get_dof_map
const DofMap & get_dof_map() const
Definition: system.h:2099
libMesh::System::n_dofs
dof_id_type n_dofs() const
Definition: system.C:150
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::CondensedEigenSystem::condensed_dofs_initialized
bool condensed_dofs_initialized
A private flag to indicate whether the condensed dofs have been initialized.
Definition: condensed_eigen_system.h:132
libMesh::EigenSystem::set_n_iterations
void set_n_iterations(unsigned int its)
Set the _n_iterations member, useful for subclasses of EigenSystem.
Definition: eigen_system.h:219
libMesh::Parameters::get
const T & get(const std::string &) const
Definition: parameters.h:421
libMesh::System::update
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition: system.C:408
libMesh::CondensedEigenSystem::n_global_non_condensed_dofs
dof_id_type n_global_non_condensed_dofs() const
Definition: condensed_eigen_system.C:74
libMesh::DofMap::end_dof
dof_id_type end_dof(const processor_id_type proc) const
Definition: dof_map.h:692
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