eigen_system.C
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 #include "libmesh/libmesh_config.h" 00020 00021 // Currently, the EigenSystem should only be available 00022 // if SLEPc support is enabled. 00023 #if defined(LIBMESH_HAVE_SLEPC) 00024 00025 // C++ includes 00026 00027 // Local includes 00028 #include "libmesh/eigen_system.h" 00029 #include "libmesh/equation_systems.h" 00030 #include "libmesh/sparse_matrix.h" 00031 #include "libmesh/eigen_solver.h" 00032 #include "libmesh/dof_map.h" 00033 #include "libmesh/mesh_base.h" 00034 00035 namespace libMesh 00036 { 00037 00038 00039 // ------------------------------------------------------------ 00040 // EigenSystem implementation 00041 EigenSystem::EigenSystem (EquationSystems& es, 00042 const std::string& name, 00043 const unsigned int number 00044 ) : 00045 Parent (es, name, number), 00046 matrix_A (NULL), 00047 matrix_B (NULL), 00048 eigen_solver (EigenSolver<Number>::build()), 00049 _n_converged_eigenpairs (0), 00050 _n_iterations (0), 00051 _is_generalized_eigenproblem (false), 00052 _eigen_problem_type (NHEP) 00053 { 00054 } 00055 00056 00057 00058 EigenSystem::~EigenSystem () 00059 { 00060 // clear data 00061 this->clear(); 00062 } 00063 00064 00065 00066 void EigenSystem::clear () 00067 { 00068 // Clear the parent data 00069 Parent::clear(); 00070 00071 // delete the matricies 00072 delete matrix_A; 00073 delete matrix_B; 00074 00075 // NULL-out the matricies. 00076 matrix_A = NULL; 00077 matrix_B = NULL; 00078 00079 // clear the solver 00080 eigen_solver->clear(); 00081 00082 } 00083 00084 00085 void EigenSystem::set_eigenproblem_type (EigenProblemType ept) 00086 { 00087 _eigen_problem_type = ept; 00088 00089 eigen_solver->set_eigenproblem_type(ept); 00090 00091 // libMesh::out<< "The Problem type is set to be: "<<std::endl; 00092 00093 switch (_eigen_problem_type) 00094 { 00095 case HEP: // libMesh::out<<"Hermitian"<<std::endl; 00096 break; 00097 00098 case NHEP: // libMesh::out<<"Non-Hermitian"<<std::endl; 00099 break; 00100 00101 case GHEP: // libMesh::out<<"Gerneralized Hermitian"<<std::endl; 00102 break; 00103 00104 case GNHEP: // libMesh::out<<"Generalized Non-Hermitian"<<std::endl; 00105 break; 00106 00107 default: // libMesh::out<<"not properly specified"<<std::endl; 00108 libmesh_error(); 00109 break; 00110 00111 } 00112 } 00113 00114 00115 00116 00117 void EigenSystem::init_data () 00118 { 00119 // initialize parent data 00120 Parent::init_data(); 00121 00122 // define the type of eigenproblem 00123 if (_eigen_problem_type == GNHEP || _eigen_problem_type == GHEP) 00124 _is_generalized_eigenproblem = true; 00125 00126 // build the system matrix 00127 matrix_A = SparseMatrix<Number>::build().release(); 00128 00129 this->init_matrices(); 00130 } 00131 00132 00133 00134 void EigenSystem::init_matrices () 00135 { 00136 DofMap& dof_map = this->get_dof_map(); 00137 00138 dof_map.attach_matrix(*matrix_A); 00139 00140 // build matrix_B only in case of a 00141 // generalized problem 00142 if (_is_generalized_eigenproblem) 00143 { 00144 matrix_B = SparseMatrix<Number>::build().release(); 00145 dof_map.attach_matrix(*matrix_B); 00146 } 00147 00148 dof_map.compute_sparsity(this->get_mesh()); 00149 00150 // initialize and zero system matrix 00151 matrix_A->init(); 00152 matrix_A->zero(); 00153 00154 // eventually initialize and zero system matrix_B 00155 if (_is_generalized_eigenproblem) 00156 { 00157 matrix_B->init(); 00158 matrix_B->zero(); 00159 } 00160 } 00161 00162 00163 00164 void EigenSystem::reinit () 00165 { 00166 // initialize parent data 00167 Parent::reinit(); 00168 00169 // Clear the matrices 00170 matrix_A->clear(); 00171 00172 if (_is_generalized_eigenproblem) 00173 matrix_B->clear(); 00174 00175 DofMap& dof_map = this->get_dof_map(); 00176 00177 // Clear the sparsity pattern 00178 dof_map.clear_sparsity(); 00179 00180 // Compute the sparsity pattern for the current 00181 // mesh and DOF distribution. This also updates 00182 // both matrices, \p DofMap now knows them 00183 dof_map.compute_sparsity(this->get_mesh()); 00184 00185 matrix_A->init(); 00186 matrix_A->zero(); 00187 00188 if (_is_generalized_eigenproblem) 00189 { 00190 matrix_B->init(); 00191 matrix_B->zero(); 00192 } 00193 } 00194 00195 00196 00197 void EigenSystem::solve () 00198 { 00199 00200 // A reference to the EquationSystems 00201 EquationSystems& es = this->get_equation_systems(); 00202 00203 // check that necessary parameters have been set 00204 libmesh_assert (es.parameters.have_parameter<unsigned int>("eigenpairs")); 00205 libmesh_assert (es.parameters.have_parameter<unsigned int>("basis vectors")); 00206 00207 if (this->assemble_before_solve) 00208 // Assemble the linear system 00209 this->assemble (); 00210 00211 // Get the tolerance for the solver and the maximum 00212 // number of iterations. Here, we simply adopt the linear solver 00213 // specific parameters. 00214 const Real tol = 00215 es.parameters.get<Real>("linear solver tolerance"); 00216 00217 const unsigned int maxits = 00218 es.parameters.get<unsigned int>("linear solver maximum iterations"); 00219 00220 const unsigned int nev = 00221 es.parameters.get<unsigned int>("eigenpairs"); 00222 00223 const unsigned int ncv = 00224 es.parameters.get<unsigned int>("basis vectors"); 00225 00226 std::pair<unsigned int, unsigned int> solve_data; 00227 00228 // call the solver depending on the type of eigenproblem 00229 if (_is_generalized_eigenproblem) 00230 { 00231 //in case of a generalized eigenproblem 00232 solve_data = eigen_solver->solve_generalized (*matrix_A,*matrix_B, nev, ncv, tol, maxits); 00233 00234 } 00235 00236 else 00237 { 00238 libmesh_assert (!matrix_B); 00239 00240 //in case of a standard eigenproblem 00241 solve_data = eigen_solver->solve_standard (*matrix_A, nev, ncv, tol, maxits); 00242 00243 } 00244 00245 this->_n_converged_eigenpairs = solve_data.first; 00246 this->_n_iterations = solve_data.second; 00247 00248 } 00249 00250 00251 void EigenSystem::assemble () 00252 { 00253 00254 // Assemble the linear system 00255 Parent::assemble (); 00256 00257 } 00258 00259 00260 std::pair<Real, Real> EigenSystem::get_eigenpair (unsigned int i) 00261 { 00262 // call the eigen_solver get_eigenpair method 00263 return eigen_solver->get_eigenpair (i, *solution); 00264 } 00265 00266 } // namespace libMesh 00267 00268 #endif // LIBMESH_HAVE_SLEPC
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:46 UTC
Hosted By: