$extrastylesheet
trilinos_aztec_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 #include "libmesh/libmesh_common.h"
00021 
00022 #ifdef LIBMESH_HAVE_AZTECOO
00023 
00024 
00025 // C++ includes
00026 
00027 // Local Includes
00028 #include "libmesh/libmesh_logging.h"
00029 #include "libmesh/string_to_enum.h"
00030 #include "libmesh/trilinos_aztec_linear_solver.h"
00031 #include "libmesh/trilinos_epetra_matrix.h"
00032 #include "libmesh/trilinos_epetra_vector.h"
00033 
00034 namespace libMesh
00035 {
00036 
00037 
00038 /*----------------------- functions ----------------------------------*/
00039 template <typename T>
00040 void AztecLinearSolver<T>::clear ()
00041 {
00042   if (this->initialized())
00043     {
00044       this->_is_initialized = false;
00045 
00046       // Mimic PETSc default solver and preconditioner
00047       this->_solver_type           = GMRES;
00048 
00049       if (this->n_processors() == 1)
00050         this->_preconditioner_type = ILU_PRECOND;
00051       else
00052         this->_preconditioner_type = BLOCK_JACOBI_PRECOND;
00053     }
00054 }
00055 
00056 
00057 
00058 template <typename T>
00059 void AztecLinearSolver<T>::init (const char * /*name*/)
00060 {
00061   // Initialize the data structures if not done so already.
00062   if (!this->initialized())
00063     {
00064       this->_is_initialized = true;
00065 
00066       _linear_solver = new AztecOO();
00067 
00068       set_solver_type();
00069 
00070       switch(this->_preconditioner_type)
00071         {
00072         case ILU_PRECOND:
00073           _linear_solver->SetAztecOption(AZ_precond,AZ_dom_decomp);
00074           _linear_solver->SetAztecOption(AZ_subdomain_solve,AZ_ilu);
00075           break;
00076 
00077         case BLOCK_JACOBI_PRECOND:
00078           _linear_solver->SetAztecOption(AZ_precond,AZ_Jacobi);
00079           break;
00080 
00081         case ICC_PRECOND:
00082           _linear_solver->SetAztecOption(AZ_precond,AZ_dom_decomp);
00083           _linear_solver->SetAztecOption(AZ_subdomain_solve,AZ_icc);
00084           break;
00085 
00086         case LU_PRECOND:
00087           _linear_solver->SetAztecOption(AZ_precond,AZ_dom_decomp);
00088           _linear_solver->SetAztecOption(AZ_subdomain_solve,AZ_lu);
00089           break;
00090 
00091         default:
00092           _linear_solver->SetAztecOption(AZ_precond,AZ_dom_decomp);
00093           _linear_solver->SetAztecOption(AZ_subdomain_solve,AZ_ilu);
00094         }
00095     }
00096 }
00097 
00098 
00099 
00100 
00101 template <typename T>
00102 std::pair<unsigned int, Real>
00103 AztecLinearSolver<T>::solve (SparseMatrix<T>& matrix_in,
00104                              SparseMatrix<T>& precond_in,
00105                              NumericVector<T>& solution_in,
00106                              NumericVector<T>& rhs_in,
00107                              const double tol,
00108                              const unsigned int m_its)
00109 {
00110   START_LOG("solve()", "AztecLinearSolver");
00111 
00112   // Make sure the data passed in are really of Epetra types
00113   EpetraMatrix<T>* matrix   = cast_ptr<EpetraMatrix<T>*>(&matrix_in);
00114   EpetraMatrix<T>* precond  = cast_ptr<EpetraMatrix<T>*>(&precond_in);
00115   EpetraVector<T>* solution = cast_ptr<EpetraVector<T>*>(&solution_in);
00116   EpetraVector<T>* rhs      = cast_ptr<EpetraVector<T>*>(&rhs_in);
00117 
00118   this->init();
00119 
00120   // Close the matrices and vectors in case this wasn't already done.
00121   matrix->close ();
00122   precond->close ();
00123   solution->close ();
00124   rhs->close ();
00125 
00126   _linear_solver->SetAztecOption(AZ_max_iter,m_its);
00127   _linear_solver->SetAztecParam(AZ_tol,tol);
00128 
00129   Epetra_FECrsMatrix * emat = matrix->mat();
00130   Epetra_Vector * esol = solution->vec();
00131   Epetra_Vector * erhs = rhs->vec();
00132 
00133   _linear_solver->Iterate(emat, esol, erhs, m_its, tol);
00134 
00135   STOP_LOG("solve()", "AztecLinearSolver");
00136 
00137   // return the # of its. and the final residual norm.
00138   return std::make_pair(_linear_solver->NumIters(), _linear_solver->TrueResidual());
00139 }
00140 
00141 
00142 
00143 template <typename T>
00144 std::pair<unsigned int, Real>
00145 AztecLinearSolver<T>::solve (const ShellMatrix<T>&,
00146                              NumericVector<T>&,
00147                              NumericVector<T>&,
00148                              const double,
00149                              const unsigned int)
00150 //AztecLinearSolver<T>::solve (const ShellMatrix<T>& shell_matrix,
00151 //     NumericVector<T>& solution_in,
00152 //     NumericVector<T>& rhs_in,
00153 //     const double tol,
00154 //     const unsigned int m_its)
00155 {
00156   libmesh_not_implemented();
00157 }
00158 
00159 
00160 
00161 template <typename T>
00162 std::pair<unsigned int, Real>
00163 AztecLinearSolver<T>::solve (const ShellMatrix<T>&,
00164                              const SparseMatrix<T>&,
00165                              NumericVector<T> &,
00166                              NumericVector<T> &,
00167                              const double,
00168                              const unsigned int)
00169 //AztecLinearSolver<T>::solve (const ShellMatrix<T>& shell_matrix,
00170 //     const SparseMatrix<T>& precond_matrix,
00171 //     NumericVector<T> &solution_in,
00172 //     NumericVector<T> &rhs_in,
00173 //     const double tol,
00174 //     const unsigned int m_its)
00175 {
00176   libmesh_not_implemented();
00177 }
00178 
00179 
00180 
00181 template <typename T>
00182 void AztecLinearSolver<T>::get_residual_history(std::vector<double>& /* hist */)
00183 {
00184   libmesh_not_implemented();
00185 }
00186 
00187 
00188 
00189 
00190 template <typename T>
00191 Real AztecLinearSolver<T>::get_initial_residual()
00192 {
00193   return _linear_solver->TrueResidual();
00194 }
00195 
00196 
00197 
00198 template <typename T>
00199 LinearConvergenceReason AztecLinearSolver<T>::get_converged_reason() const
00200 {
00201   libmesh_not_implemented();
00202 
00203   return UNKNOWN_FLAG;
00204 }
00205 
00206 
00207 
00208 template <typename T>
00209 void AztecLinearSolver<T>::set_solver_type()
00210 {
00211   switch (this->_solver_type)
00212     {
00213     case CG:
00214       _linear_solver->SetAztecOption(AZ_solver, AZ_cg); return;
00215 
00216     case CGS:
00217       _linear_solver->SetAztecOption(AZ_solver, AZ_cgs); return;
00218 
00219     case TFQMR:
00220       _linear_solver->SetAztecOption(AZ_solver, AZ_tfqmr); return;
00221 
00222     case BICGSTAB:
00223       _linear_solver->SetAztecOption(AZ_solver, AZ_bicgstab); return;
00224 
00225     case GMRES:
00226       _linear_solver->SetAztecOption(AZ_solver, AZ_gmres); return;
00227 
00228     default:
00229       libMesh::err << "ERROR:  Unsupported AztecOO Solver: "
00230                    << Utility::enum_to_string(this->_solver_type) << std::endl
00231                    << "Continuing with AztecOO defaults" << std::endl;
00232     }
00233 }
00234 
00235 //------------------------------------------------------------------
00236 // Explicit instantiations
00237 template class AztecLinearSolver<Number>;
00238 
00239 } // namespace libMesh
00240 
00241 
00242 
00243 #endif // #ifdef LIBMESH_HAVE_AZTECOO