$extrastylesheet
linear_solver.C
Go to the documentation of this file.
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