$extrastylesheet
00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2014 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 00020 // C++ includes 00021 00022 // Local Includes 00023 #include "libmesh/libmesh_logging.h" 00024 #include "libmesh/auto_ptr.h" 00025 #include "libmesh/linear_solver.h" 00026 #include "libmesh/laspack_linear_solver.h" 00027 #include "libmesh/eigen_sparse_linear_solver.h" 00028 #include "libmesh/petsc_linear_solver.h" 00029 #include "libmesh/trilinos_aztec_linear_solver.h" 00030 #include "libmesh/preconditioner.h" 00031 #include "libmesh/sparse_matrix.h" 00032 #include "libmesh/string_to_enum.h" 00033 00034 namespace libMesh 00035 { 00036 00037 //------------------------------------------------------------------ 00038 // LinearSolver members 00039 template <typename T> 00040 UniquePtr<LinearSolver<T> > 00041 LinearSolver<T>::build(const libMesh::Parallel::Communicator &comm, 00042 const SolverPackage solver_package) 00043 { 00044 // Build the appropriate solver 00045 switch (solver_package) 00046 { 00047 00048 00049 #ifdef LIBMESH_HAVE_LASPACK 00050 case LASPACK_SOLVERS: 00051 return UniquePtr<LinearSolver<T> >(new LaspackLinearSolver<T>(comm)); 00052 #endif 00053 00054 00055 #ifdef LIBMESH_HAVE_PETSC 00056 case PETSC_SOLVERS: 00057 return UniquePtr<LinearSolver<T> >(new PetscLinearSolver<T>(comm)); 00058 #endif 00059 00060 00061 #ifdef LIBMESH_HAVE_TRILINOS 00062 case TRILINOS_SOLVERS: 00063 return UniquePtr<LinearSolver<T> >(new AztecLinearSolver<T>(comm)); 00064 #endif 00065 00066 00067 #ifdef LIBMESH_HAVE_EIGEN 00068 case EIGEN_SOLVERS: 00069 return UniquePtr<LinearSolver<T> >(new EigenSparseLinearSolver<T>(comm)); 00070 #endif 00071 00072 default: 00073 libmesh_error_msg("ERROR: Unrecognized solver package: " << solver_package); 00074 } 00075 00076 return UniquePtr<LinearSolver<T> >(); 00077 } 00078 00079 template <typename T> 00080 PreconditionerType 00081 LinearSolver<T>::preconditioner_type () const 00082 { 00083 if(_preconditioner) 00084 return _preconditioner->type(); 00085 00086 return _preconditioner_type; 00087 } 00088 00089 template <typename T> 00090 void 00091 LinearSolver<T>::set_preconditioner_type (const PreconditionerType pct) 00092 { 00093 if(_preconditioner) 00094 _preconditioner->set_type(pct); 00095 else 00096 _preconditioner_type = pct; 00097 } 00098 00099 template <typename T> 00100 void 00101 LinearSolver<T>::attach_preconditioner(Preconditioner<T> * preconditioner) 00102 { 00103 if (this->_is_initialized) 00104 libmesh_error_msg("Preconditioner must be attached before the solver is initialized!"); 00105 00106 _preconditioner_type = SHELL_PRECOND; 00107 _preconditioner = preconditioner; 00108 } 00109 00110 template <typename T> 00111 void 00112 LinearSolver<T>::reuse_preconditioner(bool reuse_flag) 00113 { 00114 same_preconditioner = reuse_flag; 00115 } 00116 00117 template <typename T> 00118 void 00119 LinearSolver<T>::restrict_solve_to(const std::vector<unsigned int>* const dofs, 00120 const SubsetSolveMode /*subset_solve_mode*/) 00121 { 00122 if(dofs!=NULL) 00123 { 00124 libmesh_not_implemented(); 00125 } 00126 } 00127 00128 00129 template <typename T> 00130 std::pair<unsigned int, Real> LinearSolver<T>::adjoint_solve (SparseMatrix<T> & mat, 00131 NumericVector<T>& sol, 00132 NumericVector<T>& rhs, 00133 const double tol, 00134 const unsigned int n_iter) 00135 { 00136 // Log how long the linear solve takes. 00137 START_LOG("adjoint_solve()", "LinearSolver"); 00138 00139 // Take the discrete adjoint 00140 mat.close(); 00141 mat.get_transpose(mat); 00142 00143 // Call the solve function for the relevant linear algebra library and 00144 // solve the transpose matrix 00145 const std::pair<unsigned int, Real> totalrval = this->solve (mat, sol, rhs, tol, n_iter); 00146 00147 // Now transpose back and restore the original matrix 00148 // by taking the discrete adjoint 00149 mat.get_transpose(mat); 00150 00151 // Stop logging the nonlinear solve 00152 STOP_LOG("adjoint_solve()", "LinearSolver"); 00153 00154 return totalrval; 00155 00156 } 00157 00158 template <typename T> 00159 void LinearSolver<T>::print_converged_reason() const 00160 { 00161 LinearConvergenceReason reason = this->get_converged_reason(); 00162 libMesh::out << "Linear solver convergence/divergence reason: " << Utility::enum_to_string(reason) << std::endl; 00163 } 00164 00165 //------------------------------------------------------------------ 00166 // Explicit instantiations 00167 template class LinearSolver<Number>; 00168 00169 00170 00171 } // namespace libMesh