IFPACK  Development
 All Classes Files Functions Variables Enumerations Friends
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 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 //@HEADER
00041 */
00042 #include "Ifpack_ConfigDefs.h"
00043 #include "Ifpack.h"
00044 #include "Ifpack_Preconditioner.h"
00045 #include "Ifpack_PointRelaxation.h"
00046 #include "Ifpack_BlockRelaxation.h"
00047 #include "Ifpack_IC.h"
00048 #include "Ifpack_ICT.h"
00049 #include "Ifpack_ILU.h"
00050 #include "Ifpack_SILU.h"
00051 #include "Ifpack_ILUT.h"
00052 #include "Ifpack_SPARSKIT.h"
00053 #include "Ifpack_AdditiveSchwarz.h"
00054 #include "Ifpack_DenseContainer.h"
00055 #include "Ifpack_TriDiContainer.h"
00056 #include "Ifpack_SparseContainer.h"
00057 #ifdef HAVE_IFPACK_AMESOS
00058 #include "Ifpack_Amesos.h"
00059 #endif
00060 #ifdef HAVE_IFPACK_HIPS
00061 #include "Ifpack_HIPS.h"
00062 #endif
00063 #ifdef HAVE_IFPACK_SUPERLU
00064 #include "Ifpack_SILU.h"
00065 #endif
00066 #ifdef HAVE_IFPACK_SUPPORTGRAPH
00067 #include "Ifpack_SupportGraph.h"
00068 #endif
00069 
00070 #include "Ifpack_Chebyshev.h"
00071 #include "Ifpack_Polynomial.h"
00072 #include "Ifpack_Krylov.h"
00073 #include "Ifpack_IHSS.h"
00074 #include "Ifpack_SORa.h"
00075 
00076 #include "Teuchos_CommandLineProcessor.hpp"
00077 #include "Teuchos_StringToIntMap.hpp"
00078 #include "Epetra_CrsMatrix.h"
00079 
00080 
00081 namespace {
00082 
00083 const Teuchos::StringToIntMap
00084 precTypeNameToIntMap(
00085   "parameter \"Prec Type\"", Ifpack::numPrecTypes, Ifpack::precTypeNames
00086   );
00087 
00088 } // namespace
00089 
00090 //==============================================================================
00091 const Ifpack::EPrecType Ifpack::precTypeValues[Ifpack::numPrecTypes] =
00092 {
00093   POINT_RELAXATION
00094   ,POINT_RELAXATION_STAND_ALONE
00095   ,BLOCK_RELAXATION
00096   ,BLOCK_RELAXATION_STAND_ALONE
00097   ,BLOCK_RELAXATION_STAND_ALONE_ILU
00098   ,BLOCK_RELAXATION_STAND_ALONE_ILUT
00099   ,BLOCK_RELAXATION_STAND_ALONE_IC
00100 #ifdef HAVE_IFPACK_SUPERLU
00101   ,BLOCK_RELAXATION_STAND_ALONE_SILU
00102 #endif
00103 #ifdef HAVE_IFPACK_AMESOS
00104   ,BLOCK_RELAXATION_STAND_ALONE_AMESOS
00105   ,BLOCK_RELAXATION_AMESOS
00106   ,AMESOS
00107   ,AMESOS_STAND_ALONE
00108 #endif // HAVE_IFPACK_AMESOS
00109   ,IC
00110   ,IC_STAND_ALONE
00111   ,ICT
00112   ,ICT_STAND_ALONE
00113   ,ILU
00114   ,ILU_STAND_ALONE
00115   ,ILUT
00116   ,ILUT_STAND_ALONE
00117 #ifdef HAVE_IFPACK_SPARSKIT
00118   ,SPARSKIT
00119 #endif // HAVE_IFPACK_SPARSKIT
00120 #ifdef HAVE_IFPACK_HIPS
00121   ,HIPS
00122 #endif
00123 #ifdef HAVE_HYPRE
00124   ,HYPRE
00125 #endif
00126 #ifdef HAVE_IFPACK_SUPERLU
00127   ,SILU
00128 #endif
00129 #if defined (HAVE_IFPACK_SUPPORTGRAPH) && defined (HAVE_IFPACK_AMESOS)
00130   ,MSF_AMESOS
00131 #endif
00132 #ifdef HAVE_IFPACK_SUPPORTGRAPH
00133   ,MSF_IC
00134 #endif
00135   ,CHEBYSHEV
00136   ,POLYNOMIAL
00137   ,KRYLOV
00138   ,IHSS
00139   ,SORA
00140   ,TRIDI_RELAXATION
00141   ,TRIDI_RELAXATION_STAND_ALONE
00142 };
00143 
00144 //==============================================================================
00145 const char* Ifpack::precTypeNames[Ifpack::numPrecTypes] =
00146 {
00147   "point relaxation"
00148   ,"point relaxation stand-alone"
00149   ,"block relaxation"
00150   ,"block relaxation stand-alone"
00151   ,"block relaxation stand-alone (ILU)"
00152   ,"block relaxation stand-alone (ILUT)"
00153   ,"block relaxation stand-alone (IC)"
00154 #ifdef HAVE_IFPACK_SUPERLU
00155   ,"block relaxation stand-alone (SILU)"
00156 #endif
00157 #ifdef HAVE_IFPACK_AMESOS
00158   ,"block relaxation stand-alone (Amesos)"
00159   ,"block relaxation (Amesos)"
00160   ,"Amesos"
00161   ,"Amesos stand-alone"
00162 #endif
00163   ,"IC"
00164   ,"IC stand-alone"
00165   ,"ICT"
00166   ,"ICT stand-alone"
00167   ,"ILU"
00168   ,"ILU stand-alone"
00169   ,"ILUT"
00170   ,"ILUT stand-alone"
00171 #ifdef HAVE_IFPACK_SPARSKIT
00172   ,"SPARSKIT"
00173 #endif
00174 #ifdef HAVE_IFPACK_HIPS
00175   ,"HIPS"
00176 #endif
00177 #ifdef HAVE_HYPRE
00178   ,"Hypre"
00179 #endif
00180 #ifdef HAVE_IFPACK_SUPERLU
00181   ,"SILU"
00182 #endif
00183 #if defined (HAVE_IFPACK_SUPPORTGRAPH) && defined (HAVE_IFPACK_AMESOS)
00184   ,"MSF Amesos"
00185 #endif
00186 #ifdef HAVE_IFPACK_SUPPORTGRAPH
00187   ,"MSF IC"
00188 #endif
00189   ,"Chebyshev"
00190   ,"Polynomial"
00191   ,"Krylov"
00192   ,"IHSS"
00193   ,"SORa"
00194   ,"tridi relaxation"
00195   ,"tridi relaxation stand-alone"
00196 };
00197 
00198 //==============================================================================
00199 const bool Ifpack::supportsUnsymmetric[Ifpack::numPrecTypes] =
00200 {
00201   true // point relaxation
00202   ,true // point relaxation stand-alone
00203   ,true // block relaxation
00204   ,true // block relaxation stand-alone
00205   ,true // block relaxation stand-alone (ILU)
00206   ,true // block relaxation stand-alone (ILUT)
00207   ,false // block relaxation stand-alone (IC)
00208 #ifdef HAVE_IFPACK_SUPERLU
00209   ,true // block relaxation stand-alone (SILU)
00210 #endif
00211 #ifdef HAVE_IFPACK_AMESOS
00212   ,true // block relaxation stand-alone (Amesos)
00213   ,true // block relaxation (Amesos)
00214   ,true // Amesos
00215   ,true // Amesos stand-alone 
00216 #endif
00217   ,false // IC
00218   ,false // IC stand-alone
00219   ,false // ICT
00220   ,false // ICT stand-alone
00221   ,true // ILU
00222   ,true // ILU stand-alone
00223   ,true // ILUT
00224   ,true // ILUT stand-alone
00225 #ifdef HAVE_IFPACK_SPARSKIT
00226   ,true // SPARSKIT
00227 #endif
00228 #ifdef HAVE_IFPACK_HIPS
00229   ,true // HIPS
00230 #endif  
00231 #ifdef HAVE_HYPRE
00232   ,true
00233 #endif
00234 #ifdef HAVE_IFPACK_SUPERLU
00235   ,true // SuperLU's Supernodal ILUTP
00236 #endif
00237 #if defined (HAVE_IFPACK_SUPPORTGRAPH) && defined (HAVE_IFPACK_AMESOS)
00238   ,false
00239 #endif
00240 #ifdef HAVE_IFPACK_SUPPORTGRAPH
00241   ,false
00242 #endif
00243   ,false // CHEBYSHEV
00244   ,true  // POLYNOMIAL
00245   ,true  // KRYLOV
00246   ,true  // IHSS
00247   ,true  // SORa
00248   ,true  // tridi relaxation
00249   ,true  // tridi relaxation standalone
00250 };
00251 
00252 //==============================================================================
00253 Ifpack_Preconditioner* Ifpack::Create(EPrecType PrecType,
00254                                       Epetra_RowMatrix* Matrix,
00255                                       const int Overlap,
00256                                       bool overrideSerialDefault)
00257 {
00258   const bool serial = (Matrix->Comm().NumProc() == 1);
00259 
00260   switch(PrecType) {
00261     case POINT_RELAXATION:
00262       if (serial && !overrideSerialDefault)
00263         return(new Ifpack_PointRelaxation(Matrix));
00264       else
00265         return(new Ifpack_AdditiveSchwarz<Ifpack_PointRelaxation>(Matrix, Overlap));
00266     case POINT_RELAXATION_STAND_ALONE:
00267       return(new Ifpack_PointRelaxation(Matrix));
00268     case BLOCK_RELAXATION:
00269       if (serial && !overrideSerialDefault)
00270         return(new Ifpack_BlockRelaxation<Ifpack_DenseContainer>(Matrix));
00271       else
00272         return(new Ifpack_AdditiveSchwarz<
00273              Ifpack_BlockRelaxation<Ifpack_DenseContainer> >(Matrix,Overlap));
00274     case BLOCK_RELAXATION_STAND_ALONE:
00275       return(new Ifpack_BlockRelaxation<Ifpack_DenseContainer>(Matrix));
00276     case BLOCK_RELAXATION_STAND_ALONE_ILU:
00277       return(new Ifpack_BlockRelaxation<Ifpack_SparseContainer<Ifpack_ILU> >(Matrix));
00278     case BLOCK_RELAXATION_STAND_ALONE_ILUT:
00279       return(new Ifpack_BlockRelaxation<Ifpack_SparseContainer<Ifpack_ILUT> >(Matrix));
00280     case BLOCK_RELAXATION_STAND_ALONE_IC:
00281       return(new Ifpack_BlockRelaxation<Ifpack_SparseContainer<Ifpack_IC> >(Matrix));
00282 #ifdef HAVE_IFPACK_SUPERLU
00283     case BLOCK_RELAXATION_STAND_ALONE_SILU:
00284       return(new Ifpack_BlockRelaxation<Ifpack_SparseContainer<Ifpack_SILU> >(Matrix));
00285 #endif
00286 #ifdef HAVE_IFPACK_AMESOS
00287     case BLOCK_RELAXATION_STAND_ALONE_AMESOS:
00288       return(new Ifpack_BlockRelaxation<Ifpack_SparseContainer<Ifpack_Amesos> >(Matrix));
00289     case BLOCK_RELAXATION_AMESOS:
00290       return(new Ifpack_AdditiveSchwarz<
00291              Ifpack_BlockRelaxation<Ifpack_SparseContainer<Ifpack_Amesos> > >(Matrix,Overlap));
00292     case AMESOS:
00293       if (serial && !overrideSerialDefault)
00294         return(new Ifpack_Amesos(Matrix));
00295       else
00296         return(new Ifpack_AdditiveSchwarz<Ifpack_Amesos>(Matrix,Overlap));
00297     case AMESOS_STAND_ALONE:
00298       return(new Ifpack_Amesos(Matrix));
00299 #endif
00300     case IC:
00301       if (serial && !overrideSerialDefault)
00302         return(new Ifpack_IC(Matrix));
00303       else
00304         return(new Ifpack_AdditiveSchwarz<Ifpack_IC>(Matrix,Overlap));
00305     case IC_STAND_ALONE:
00306       return(new Ifpack_IC(Matrix));
00307     case ICT:
00308       if (serial && !overrideSerialDefault)
00309         return(new Ifpack_ICT(Matrix));
00310       else
00311         return(new Ifpack_AdditiveSchwarz<Ifpack_ICT>(Matrix,Overlap));
00312     case ICT_STAND_ALONE:
00313       return(new Ifpack_ICT(Matrix));
00314     case ILU:
00315       if (serial && !overrideSerialDefault)
00316         return(new Ifpack_ILU(Matrix));
00317       else
00318         return(new Ifpack_AdditiveSchwarz<Ifpack_ILU>(Matrix,Overlap));
00319     case ILU_STAND_ALONE:
00320       return(new Ifpack_ILU(Matrix));
00321     case ILUT:
00322       if (serial && !overrideSerialDefault)
00323         return(new Ifpack_ILUT(Matrix));
00324       else
00325         return(new Ifpack_AdditiveSchwarz<Ifpack_ILUT>(Matrix,Overlap));
00326     case ILUT_STAND_ALONE:
00327       return(new Ifpack_ILUT(Matrix));
00328 #ifdef HAVE_IFPACK_SPARSKIT
00329     case SPARSKIT:
00330       return(new Ifpack_SPARSKIT(Matrix));
00331 #endif
00332 #ifdef HAVE_IFPACK_HIPS
00333     case HIPS:      
00334       return(new Ifpack_HIPS(Matrix));
00335 #endif      
00336 #ifdef HAVE_HYPRE
00337     case HYPRE:
00338       return(new Ifpack_Hypre(Matrix));
00339 #endif
00340 #ifdef HAVE_IFPACK_SUPERLU
00341     case SILU:
00342       return(new Ifpack_SILU(Matrix));
00343 #endif
00344 #if defined (HAVE_IFPACK_SUPPORTGRAPH) && defined (HAVE_IFPACK_AMESOS)
00345     case MSF_AMESOS:
00346       if (serial && !overrideSerialDefault)
00347     return(new Ifpack_SupportGraph<Ifpack_Amesos>(Matrix));
00348       else
00349     return(new Ifpack_AdditiveSchwarz<Ifpack_SupportGraph<Ifpack_Amesos> >(Matrix,Overlap));
00350 #endif
00351 #ifdef HAVE_IFPACK_SUPPORTGRAPH
00352     case MSF_IC:
00353       if (serial && !overrideSerialDefault)
00354     return(new Ifpack_SupportGraph<Ifpack_SupportGraph<Ifpack_IC> >(Matrix));
00355       else
00356     return(new Ifpack_AdditiveSchwarz<Ifpack_SupportGraph<Ifpack_IC> >(Matrix,Overlap));
00357 #endif
00358     case CHEBYSHEV:
00359       return(new Ifpack_Chebyshev(Matrix));
00360     case POLYNOMIAL:
00361       return(new Ifpack_Polynomial(Matrix));
00362     case KRYLOV:
00363       if (serial && !overrideSerialDefault)
00364         return(new Ifpack_Krylov(Matrix));
00365       else
00366         return(new Ifpack_AdditiveSchwarz<Ifpack_Krylov>(Matrix, Overlap));
00367 #ifdef HAVE_IFPACK_EPETRAEXT
00368     case IHSS:
00369       return(new Ifpack_IHSS(Matrix));  
00370     case SORA:
00371       return(new Ifpack_SORa(Matrix));  
00372 #endif
00373     case TRIDI_RELAXATION:
00374      if (serial && !overrideSerialDefault)
00375       return(new Ifpack_BlockRelaxation<Ifpack_TriDiContainer>(Matrix));
00376      else
00377       return(new Ifpack_AdditiveSchwarz<
00378              Ifpack_BlockRelaxation<Ifpack_TriDiContainer> >(Matrix,Overlap));
00379     case TRIDI_RELAXATION_STAND_ALONE:
00380       return(new Ifpack_BlockRelaxation<Ifpack_TriDiContainer>(Matrix));
00381     default:
00382       TEUCHOS_TEST_FOR_EXCEPT(true);
00383       // The only way to get here is if some code developer does a cast like
00384       // (EPrecType)(anyNumber).  You can never get here by passing in a
00385       // string value for the preconditioner!
00386   } // end switch
00387   return 0; // This will never ever be executed!
00388 }
00389 
00390 //==============================================================================
00391 Ifpack_Preconditioner* Ifpack::Create(const string PrecType,
00392                                       Epetra_RowMatrix* Matrix,
00393                                       const int Overlap,
00394                                       bool overrideSerialDefault)
00395 {
00396   try {
00397     return Ifpack::Create(Teuchos::get<EPrecType>(::precTypeNameToIntMap,PrecType),Matrix,Overlap,overrideSerialDefault);
00398   }
00399   catch( const Teuchos::StringToIntMap::DoesNotExist &excpt ) {
00400     // The old implementation of this function just silently returned a NULL
00401     // when a preconditiner type name was not recognized.  If you like this
00402     // behavior then you should use this function.  If you do not like this
00403     // behavior, then consider using the Ifpack/Thyra adapter
00404     // Thyra::IfpackPreconditionerFactory or better yet the Stratimikos
00405     // wrapper class Stratimikos::DefaultLinearSolverBuilder.
00406   }
00407   return 0;
00408 }
00409 
00410 // ======================================================================
00411 int Ifpack::SetParameters(int argc, char* argv[],
00412                           Teuchos::ParameterList& List, string& PrecType,
00413                           int& Overlap)
00414 {
00415   // THIS FUNCTION IS VERY INCOMPLETE...
00416 
00417   Teuchos::CommandLineProcessor CLP;
00418 
00419   // prec type
00420   string ifp_prec_type = "ILU";
00421   CLP.setOption("ifp-prec-type",&ifp_prec_type,"Preconditioner type");
00422   // overlap among the processors
00423   int ifp_overlap = 0;
00424   CLP.setOption("ifp-overlap",&ifp_overlap,"Overlap among processors");
00425   // relaxation type
00426   string ifp_relax_type = "Jacobi";
00427   CLP.setOption("ifp-relax-type",&ifp_relax_type,"Relaxation type");
00428   // sweeps (for relax only)
00429   int ifp_relax_sweeps = 1;
00430   CLP.setOption("ifp-relax-sweeps",
00431                 &ifp_relax_sweeps,"Number of sweeps for relaxation");
00432   // damping (for relax only)
00433   double ifp_relax_damping = 1.0;
00434   CLP.setOption("ifp-relax-damping",
00435                 &ifp_relax_damping,"Damping for relaxation");
00436   // partitioner type (for block relaxation only)
00437   string ifp_part_type = "greedy";
00438   CLP.setOption("ifp-part-type",&ifp_part_type,"Partitioner type");
00439   // number of local parts (for block relaxation only)
00440   int ifp_part_local = 1;
00441   CLP.setOption("ifp-part-local",&ifp_part_local,"number of local partitions");
00442 
00443   // allow users to specify other options for other packages
00444   CLP.recogniseAllOptions(false);
00445   CLP.throwExceptions(false);
00446   CLP.parse(argc,argv);
00447 
00448   // I cannot really set those in the List, I pass them back to the user
00449   PrecType = ifp_prec_type;
00450   Overlap = ifp_overlap;
00451 
00452   // set the list here
00453   List.set("relaxation: type", ifp_relax_type);
00454   List.set("relaxation: sweeps", ifp_relax_sweeps);
00455   List.set("relaxation: damping factor", ifp_relax_damping);
00456   List.set("partitioner: type", ifp_part_type);
00457   List.set("partitioner: local parts", ifp_part_local);
00458 
00459   return(0);
00460 }
 All Classes Files Functions Variables Enumerations Friends