$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 #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