Ifpack.cpp

00001 /*@HEADER
00002 // ***********************************************************************
00003 //
00004 //       Ifpack: Object-Oriented Algebraic Preconditioner Package
00005 //                 Copyright (2002) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 //@HEADER
00028 */
00029 
00030 #include "Ifpack_ConfigDefs.h"
00031 #include "Ifpack.h"
00032 #include "Ifpack_Preconditioner.h"
00033 #include "Ifpack_PointRelaxation.h"
00034 #include "Ifpack_BlockRelaxation.h"
00035 #include "Ifpack_IC.h"
00036 #include "Ifpack_ICT.h"
00037 #include "Ifpack_ILU.h"
00038 #include "Ifpack_ILUT.h"
00039 #include "Ifpack_SPARSKIT.h"
00040 #include "Ifpack_AdditiveSchwarz.h"
00041 #include "Ifpack_DenseContainer.h"
00042 #include "Ifpack_SparseContainer.h"
00043 #ifdef HAVE_IFPACK_AMESOS
00044 #include "Ifpack_Amesos.h"
00045 #endif
00046 #ifdef HAVE_IFPACK_HIPS
00047 #include "Ifpack_HIPS.h"
00048 #endif
00049 
00050 #include "Ifpack_Chebyshev.h"
00051 
00052 #include "Teuchos_CommandLineProcessor.hpp"
00053 #include "Teuchos_StringToIntMap.hpp"
00054 #include "Epetra_CrsMatrix.h"
00055 
00056 
00057 namespace {
00058 
00059 const Teuchos::StringToIntMap
00060 precTypeNameToIntMap(
00061   "parameter \"Prec Type\"", Ifpack::numPrecTypes, Ifpack::precTypeNames
00062   );
00063 
00064 } // namespace
00065 
00066 //==============================================================================
00067 const Ifpack::EPrecType Ifpack::precTypeValues[Ifpack::numPrecTypes] =
00068 {
00069   POINT_RELAXATION
00070   ,POINT_RELAXATION_STAND_ALONE
00071   ,BLOCK_RELAXATION
00072   ,BLOCK_RELAXATION_STAND_ALONE
00073   ,BLOCK_RELAXATION_STAND_ALONE_ILU
00074 #ifdef HAVE_IFPACK_AMESOS
00075   ,BLOCK_RELAXATION_STAND_ALONE_AMESOS
00076   ,BLOCK_RELAXATION_AMESOS
00077   ,AMESOS
00078   ,AMESOS_STAND_ALONE
00079 #endif // HAVE_IFPACK_AMESOS
00080   ,IC
00081   ,IC_STAND_ALONE
00082   ,ICT
00083   ,ICT_STAND_ALONE
00084   ,ILU
00085   ,ILU_STAND_ALONE
00086   ,ILUT
00087   ,ILUT_STAND_ALONE
00088 #ifdef HAVE_IFPACK_SPARSKIT
00089   ,SPARSKIT
00090 #endif // HAVE_IFPACK_SPARSKIT
00091 #ifdef HAVE_IFPACK_HIPS
00092   ,HIPS
00093 #endif
00094 #ifdef HAVE_HYPRE
00095   ,HYPRE
00096 #endif
00097   ,CHEBYSHEV
00098 };
00099 
00100 //==============================================================================
00101 const char* Ifpack::precTypeNames[Ifpack::numPrecTypes] =
00102 {
00103   "point relaxation"
00104   ,"point relaxation stand-alone"
00105   ,"block relaxation"
00106   ,"block relaxation stand-alone"
00107   ,"block relaxation stand-alone (ILU)"
00108 #ifdef HAVE_IFPACK_AMESOS
00109   ,"block relaxation stand-alone (Amesos)"
00110   ,"block relaxation (Amesos)"
00111   ,"Amesos"
00112   ,"Amesos stand-alone"
00113 #endif
00114   ,"IC"
00115   ,"IC stand-alone"
00116   ,"ICT"
00117   ,"ICT stand-alone"
00118   ,"ILU"
00119   ,"ILU stand-alone"
00120   ,"ILUT"
00121   ,"ILUT stand-alone"
00122 #ifdef HAVE_IFPACK_SPARSKIT
00123   ,"SPARSKIT"
00124 #endif
00125 #ifdef HAVE_IFPACK_HIPS
00126   ,"HIPS"
00127 #endif
00128 #ifdef HAVE_HYPRE
00129   ,"Hypre"
00130 #endif
00131   ,"Chebyshev"
00132 };
00133 
00134 //==============================================================================
00135 const bool Ifpack::supportsUnsymmetric[Ifpack::numPrecTypes] =
00136 {
00137   true // point relaxation
00138   ,true // point relaxation stand-alone
00139   ,true // block relaxation
00140   ,true // block relaxation stand-alone
00141   ,true // block relaxation stand-alone (ILU)
00142 #ifdef HAVE_IFPACK_AMESOS
00143   ,true // block relaxation stand-alone (Amesos)
00144   ,true // block relaxation (Amesos)
00145   ,true // Amesos
00146   ,true // Amesos stand-alone 
00147 #endif
00148   ,false // IC
00149   ,false // IC stand-alone
00150   ,false // ICT
00151   ,false // ICT stand-alone
00152   ,true // ILU
00153   ,true // ILU stand-alone
00154   ,true // ILUT
00155   ,true // ILUT stand-alone
00156 #ifdef HAVE_IFPACK_SPARSKIT
00157   ,true // SPARSKIT
00158 #endif
00159 #ifdef HAVE_IFPACK_HIPS
00160   ,true // HIPS
00161 #endif  
00162 #ifdef HAVE_HYPRE
00163   ,true
00164 #endif
00165   ,false // CHEBYSHEV
00166 };
00167 
00168 //==============================================================================
00169 Ifpack_Preconditioner* Ifpack::Create(EPrecType PrecType,
00170                                       Epetra_RowMatrix* Matrix,
00171                                       const int Overlap)
00172 {
00173   switch(PrecType) {
00174     case POINT_RELAXATION:
00175       return(new Ifpack_AdditiveSchwarz<Ifpack_PointRelaxation>(Matrix, Overlap));
00176     case POINT_RELAXATION_STAND_ALONE:
00177       return(new Ifpack_PointRelaxation(Matrix));
00178     case BLOCK_RELAXATION:
00179       return(new Ifpack_AdditiveSchwarz<
00180              Ifpack_BlockRelaxation<Ifpack_DenseContainer> >(Matrix,Overlap));
00181     case BLOCK_RELAXATION_STAND_ALONE:
00182       return(new Ifpack_BlockRelaxation<Ifpack_DenseContainer>(Matrix));
00183     case BLOCK_RELAXATION_STAND_ALONE_ILU:
00184       return(new Ifpack_BlockRelaxation<Ifpack_SparseContainer<Ifpack_ILU> >(Matrix));
00185 #ifdef HAVE_IFPACK_AMESOS
00186     case BLOCK_RELAXATION_STAND_ALONE_AMESOS:
00187       return(new Ifpack_BlockRelaxation<Ifpack_SparseContainer<Ifpack_Amesos> >(Matrix));
00188     case BLOCK_RELAXATION_AMESOS:
00189       return(new Ifpack_AdditiveSchwarz<
00190              Ifpack_BlockRelaxation<Ifpack_SparseContainer<Ifpack_Amesos> > >(Matrix,Overlap));
00191     case AMESOS:
00192       return(new Ifpack_AdditiveSchwarz<Ifpack_Amesos>(Matrix,Overlap));
00193     case AMESOS_STAND_ALONE:
00194       return(new Ifpack_Amesos(Matrix));
00195 #endif
00196     case IC:
00197       return(new Ifpack_AdditiveSchwarz<Ifpack_IC>(Matrix,Overlap));
00198     case IC_STAND_ALONE:
00199       return(new Ifpack_IC(Matrix));
00200     case ICT:
00201       return(new Ifpack_AdditiveSchwarz<Ifpack_ICT>(Matrix,Overlap));
00202     case ICT_STAND_ALONE:
00203       return(new Ifpack_ICT(Matrix));
00204     case ILU:
00205       return(new Ifpack_AdditiveSchwarz<Ifpack_ILU>(Matrix,Overlap));
00206     case ILU_STAND_ALONE:
00207       return(new Ifpack_ILU(Matrix));
00208     case ILUT:
00209       return(new Ifpack_AdditiveSchwarz<Ifpack_ILUT>(Matrix,Overlap));
00210     case ILUT_STAND_ALONE:
00211       return(new Ifpack_ILUT(Matrix));
00212 #ifdef HAVE_IFPACK_SPARSKIT
00213     case SPARSKIT:
00214       return(new Ifpack_SPARSKIT(Matrix));
00215 #endif
00216 #ifdef HAVE_IFPACK_HIPS
00217     case HIPS:      
00218       return(new Ifpack_HIPS(Matrix));
00219 #endif      
00220 #ifdef HAVE_HYPRE
00221     case HYPRE:
00222       return(new Ifpack_Hypre(Matrix));
00223 #endif
00224     case CHEBYSHEV:
00225       return(new Ifpack_Chebyshev(Matrix));
00226     default:
00227       TEST_FOR_EXCEPT(true);
00228       // The only way to get here is if some code developer does a cast like
00229       // (EPrecType)(anyNumber).  You can never get here by passing in a
00230       // string value for the preconditioner!
00231   } // end switch
00232   return 0; // This will never ever be executed!
00233 }
00234 
00235 //==============================================================================
00236 Ifpack_Preconditioner* Ifpack::Create(const string PrecType,
00237                                       Epetra_RowMatrix* Matrix,
00238                                       const int Overlap)
00239 {
00240   try {
00241     return Ifpack::Create(Teuchos::get<EPrecType>(::precTypeNameToIntMap,PrecType),Matrix,Overlap);
00242   }
00243   catch( const Teuchos::StringToIntMap::DoesNotExist &excpt ) {
00244     // The old implementation of this function just silently returned a NULL
00245     // when a preconditiner type name was not recognized.  If you like this
00246     // behavior then you should use this function.  If you do not like this
00247     // behavior, then consider using the Ifpack/Thyra adapter
00248     // Thyra::IfpackPreconditionerFactory or better yet the Stratimikos
00249     // wrapper class Stratimikos::DefaultLinearSolverBuilder.
00250   }
00251   return 0;
00252 }
00253 
00254 // ======================================================================
00255 int Ifpack::SetParameters(int argc, char* argv[],
00256                           Teuchos::ParameterList& List, string& PrecType,
00257                           int& Overlap)
00258 {
00259   // THIS FUNCTION IS VERY INCOMPLETE...
00260 
00261   Teuchos::CommandLineProcessor CLP;
00262 
00263   // prec type
00264   string ifp_prec_type = "ILU";
00265   CLP.setOption("ifp-prec-type",&ifp_prec_type,"Preconditioner type");
00266   // overlap among the processors
00267   int ifp_overlap = 0;
00268   CLP.setOption("ifp-overlap",&ifp_overlap,"Overlap among processors");
00269   // relaxation type
00270   string ifp_relax_type = "Jacobi";
00271   CLP.setOption("ifp-relax-type",&ifp_relax_type,"Relaxation type");
00272   // sweeps (for relax only)
00273   int ifp_relax_sweeps = 1;
00274   CLP.setOption("ifp-relax-sweeps",
00275                 &ifp_relax_sweeps,"Number of sweeps for relaxation");
00276   // damping (for relax only)
00277   double ifp_relax_damping = 1.0;
00278   CLP.setOption("ifp-relax-damping",
00279                 &ifp_relax_damping,"Damping for relaxation");
00280   // partitioner type (for block relaxation only)
00281   string ifp_part_type = "greedy";
00282   CLP.setOption("ifp-part-type",&ifp_part_type,"Partitioner type");
00283   // number of local parts (for block relaxation only)
00284   int ifp_part_local = 1;
00285   CLP.setOption("ifp-part-local",&ifp_part_local,"number of local partitions");
00286 
00287   // allow users to specify other options for other packages
00288   CLP.recogniseAllOptions(false);
00289   CLP.throwExceptions(false);
00290   CLP.parse(argc,argv);
00291 
00292   // I cannot really set those in the List, I pass them back to the user
00293   PrecType = ifp_prec_type;
00294   Overlap = ifp_overlap;
00295 
00296   // set the list here
00297   List.set("relaxation: type", ifp_relax_type);
00298   List.set("relaxation: sweeps", ifp_relax_sweeps);
00299   List.set("relaxation: damping factor", ifp_relax_damping);
00300   List.set("partitioner: type", ifp_part_type);
00301   List.set("partitioner: local parts", ifp_part_local);
00302 
00303   return(0);
00304 }

Generated on Tue Jul 13 09:27:13 2010 for IFPACK by  doxygen 1.4.7